Removing superfluous types and methods from Common.

This commit is contained in:
Pranav K 2015-05-07 14:27:52 -07:00
parent 61b76fd99f
commit 320507604a
50 changed files with 295 additions and 388 deletions

View File

@ -2,7 +2,6 @@
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Http.Extensions": "1.0.0-*",
"Microsoft.AspNet.Mvc.Common": { "version": "6.0.0-*", "type": "build" },
"Microsoft.Framework.NotNullAttribute.Sources": { "version": "1.0.0-*", "type": "build" }, "Microsoft.Framework.NotNullAttribute.Sources": { "version": "1.0.0-*", "type": "build" },
"Microsoft.Framework.PropertyHelper.Sources": { "version": "1.0.0-*", "type": "build" }, "Microsoft.Framework.PropertyHelper.Sources": { "version": "1.0.0-*", "type": "build" },
"Newtonsoft.Json": "6.0.6" "Newtonsoft.Json": "6.0.6"
@ -12,7 +11,6 @@
"dnxcore50": { "dnxcore50": {
"dependencies": { "dependencies": {
"Microsoft.CSharp": "4.0.0-beta-*", "Microsoft.CSharp": "4.0.0-beta-*",
"System.Collections": "4.0.10-beta-*",
"System.Collections.Concurrent": "4.0.10-beta-*", "System.Collections.Concurrent": "4.0.10-beta-*",
"System.ComponentModel.TypeConverter": "4.0.0-beta-*", "System.ComponentModel.TypeConverter": "4.0.0-beta-*",
"System.Globalization": "4.0.10-beta-*", "System.Globalization": "4.0.10-beta-*",

View File

@ -2,7 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using Microsoft.AspNet.Mvc.ModelBinding.Metadata; using Microsoft.AspNet.Mvc.ModelBinding.Metadata;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
@ -273,7 +276,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
/// <summary> /// <summary>
/// Gets a collection of metadata items for validators. /// Gets a collection of metadata items for validators.
/// </summary> /// </summary>
public abstract IReadOnlyList<object> ValidatorMetadata { get;} public abstract IReadOnlyList<object> ValidatorMetadata { get; }
/// <summary> /// <summary>
/// Gets a value indicating whether <see cref="ModelType"/> is a simple type. /// Gets a value indicating whether <see cref="ModelType"/> is a simple type.
@ -288,7 +291,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
if (_isComplexType == null) if (_isComplexType == null)
{ {
_isComplexType = !TypeHelper.HasStringConverter(ModelType); _isComplexType = !TypeDescriptor.GetConverter(ModelType).CanConvertFrom(typeof(string));
} }
return _isComplexType.Value; return _isComplexType.Value;
@ -300,7 +303,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
/// </summary> /// </summary>
public bool IsNullableValueType public bool IsNullableValueType
{ {
get { return ModelType.IsNullableValueType(); } get { return TypeHelper.IsNullableValueType(ModelType); }
} }
/// <summary> /// <summary>
@ -308,11 +311,22 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// A collection type is defined as a <see cref="Type"/> which is assignable to /// A collection type is defined as a <see cref="Type"/> which is assignable to
/// <see cref="System.Collections.IEnumerable"/>, and is not a <see cref="string"/>. /// <see cref="IEnumerable"/>, and is not a <see cref="string"/>.
/// </remarks> /// </remarks>
public bool IsCollectionType public bool IsCollectionType
{ {
get { return TypeHelper.IsCollectionType(ModelType); } get
{
if (ModelType == typeof(string))
{
// Even though string implements IEnumerable, we don't really think of it
// as a collection for the purposes of model binding.
return false;
}
// We only need to look for IEnumerable, because IEnumerable<T> extends it.
return typeof(IEnumerable).IsAssignableFrom(ModelType);
}
} }
/// <summary> /// <summary>

View File

@ -70,12 +70,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return UnwrapPossibleArrayType(cultureToUse, value, type); return UnwrapPossibleArrayType(cultureToUse, value, type);
} }
public static bool CanConvertFromString(Type destinationType)
{
return TypeHelper.IsSimpleType(UnwrapNullableType(destinationType)) ||
TypeHelper.HasStringConverter(destinationType);
}
private object UnwrapPossibleArrayType(CultureInfo culture, object value, Type destinationType) private object UnwrapPossibleArrayType(CultureInfo culture, object value, Type destinationType)
{ {
// array conversion results in four cases, as below // array conversion results in four cases, as below
@ -148,7 +142,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
if (!(canConvertFrom || converter.CanConvertTo(destinationType))) if (!(canConvertFrom || converter.CanConvertTo(destinationType)))
{ {
// EnumConverter cannot convert integer, so we verify manually // EnumConverter cannot convert integer, so we verify manually
if (destinationType.IsEnum() && (value is int)) if (destinationType.GetTypeInfo().IsEnum && (value is int))
{ {
return Enum.ToObject(destinationType, (int)value); return Enum.ToObject(destinationType, (int)value);
} }

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing;
@ -361,7 +362,7 @@ namespace Microsoft.AspNet.Mvc.ApiExplorer
// If the method is declared to return IActionResult or a derived class, that information // If the method is declared to return IActionResult or a derived class, that information
// isn't valuable to the formatter. // isn't valuable to the formatter.
if (typeof(IActionResult).IsAssignableFrom(unwrappedType)) if (typeof(IActionResult).GetTypeInfo().IsAssignableFrom(unwrappedType.GetTypeInfo()))
{ {
return null; return null;
} }

View File

@ -1,20 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNet.Mvc
{
internal static class PlatformHelper
{
private static readonly Lazy<bool> _isMono = new Lazy<bool>(() => Type.GetType("Mono.Runtime") != null);
public static bool IsMono
{
get
{
return _isMono.Value;
}
}
}
}

View File

@ -1,58 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq;
namespace Microsoft.AspNet.Mvc
{
internal static class StringHelper
{
public static string TrimSpacesAndChars(string value, params char[] chars)
{
if (string.IsNullOrWhiteSpace(value))
{
return string.Empty;
}
if (chars == null || chars.Length == 0)
{
return value.Trim();
}
var firstIndex = 0;
for (; firstIndex < value.Length; firstIndex++)
{
var currentChar = value[firstIndex];
if (!char.IsWhiteSpace(currentChar) && !chars.Any(compareChar => compareChar == currentChar))
{
break;
}
}
// We trimmed all the way
if (firstIndex == value.Length)
{
return string.Empty;
}
var lastIndex = value.Length - 1;
for (; lastIndex > firstIndex; lastIndex--)
{
var currentChar = value[lastIndex];
if (!char.IsWhiteSpace(currentChar) && !chars.Any(compareChar => compareChar == currentChar))
{
break;
}
}
if (firstIndex == 0 && lastIndex == value.Length - 1)
{
return value;
}
else
{
return value.Substring(firstIndex, lastIndex - firstIndex + 1);
}
}
}
}

View File

@ -1,113 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Reflection;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc
{
internal static class TypeExtensions
{
// NOTE: Do not make #105 worse! Do not add new extension methods that conflict w/ .NET 4.5 methods. The
// exising NETFX_CORE || DNXCORE50 methods should go away (soon).
#if NETFX_CORE || DNXCORE50
private static bool EqualTo([NotNull] this Type[] t1, [NotNull] Type[] t2)
{
if (t1.Length != t2.Length)
{
return false;
}
for (var idx = 0; idx < t1.Length; ++idx)
{
if (t1[idx] != t2[idx])
{
return false;
}
}
return true;
}
public static ConstructorInfo GetConstructor([NotNull] this Type type, Type[] types)
{
return type.GetTypeInfo().DeclaredConstructors
.Where(c => c.IsPublic)
.SingleOrDefault(c => c.GetParameters()
.Select(p => p.ParameterType).ToArray().EqualTo(types));
}
#endif
public static Type BaseType([NotNull] this Type type)
{
return type.GetTypeInfo().BaseType;
}
#if NETFX_CORE || DNXCORE50
public static Type[] GetGenericArguments([NotNull] this Type type)
{
return type.GetTypeInfo().GenericTypeArguments;
}
public static Type[] GetInterfaces([NotNull] this Type type)
{
return type.GetTypeInfo().ImplementedInterfaces.ToArray();
}
public static bool IsAssignableFrom([NotNull] this Type type, [NotNull] Type c)
{
return type.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo());
}
#endif
public static bool IsEnum([NotNull] this Type type)
{
return type.GetTypeInfo().IsEnum;
}
public static bool IsGenericType([NotNull] this Type type)
{
return type.GetTypeInfo().IsGenericType;
}
public static bool IsInterface([NotNull] this Type type)
{
return type.GetTypeInfo().IsInterface;
}
public static bool IsValueType([NotNull] this Type type)
{
return type.GetTypeInfo().IsValueType;
}
public static bool IsCompatibleWith([NotNull] this Type type, object value)
{
return (value == null && AllowsNullValue(type)) ||
(value != null && type.GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo()));
}
public static bool IsNullableValueType([NotNull] this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
public static bool AllowsNullValue([NotNull] this Type type)
{
return (!type.GetTypeInfo().IsValueType || IsNullableValueType(type));
}
public static Type[] GetTypeArgumentsIfMatch([NotNull] Type closedType, Type matchingOpenType)
{
var closedTypeInfo = closedType.GetTypeInfo();
if (!closedTypeInfo.IsGenericType)
{
return null;
}
var openType = closedType.GetGenericTypeDefinition();
return (matchingOpenType == openType) ? closedTypeInfo.GenericTypeArguments : null;
}
}
}

View File

@ -2,9 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
@ -15,12 +15,13 @@ namespace Microsoft.AspNet.Mvc
{ {
private static readonly Type TaskGenericType = typeof(Task<>); private static readonly Type TaskGenericType = typeof(Task<>);
public static Type GetTaskInnerTypeOrNull([NotNull]Type type) public static Type GetTaskInnerTypeOrNull([NotNull] Type type)
{ {
if (type.GetTypeInfo().IsGenericType && !type.GetTypeInfo().IsGenericTypeDefinition) var typeInfo = type.GetTypeInfo();
if (typeInfo.IsGenericType && !typeInfo.IsGenericTypeDefinition)
{ {
var genericTypeDefinition = type.GetGenericTypeDefinition(); var genericTypeDefinition = typeInfo.GetGenericTypeDefinition();
var genericArguments = type.GetGenericArguments(); var genericArguments = typeInfo.GenericTypeArguments;
if (genericArguments.Length == 1 && TaskGenericType == genericTypeDefinition) if (genericArguments.Length == 1 && TaskGenericType == genericTypeDefinition)
{ {
// Only Return if there is a single argument. // Only Return if there is a single argument.
@ -75,22 +76,39 @@ namespace Microsoft.AspNet.Mvc
type.Equals(typeof(Uri)); type.Equals(typeof(Uri));
} }
public static bool HasStringConverter(Type type) public static bool IsCompatibleWith([NotNull] Type type, object value)
{ {
return TypeDescriptor.GetConverter(type).CanConvertFrom(typeof(string)); return (value == null && AllowsNullValue(type)) ||
(value != null && type.GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo()));
} }
public static bool IsCollectionType(Type type) public static bool IsNullableValueType([NotNull] Type type)
{ {
if (type == typeof(string)) return Nullable.GetUnderlyingType(type) != null;
{ }
// Even though string implements IEnumerable, we don't really think of it
// as a collection for the purposes of model binding.
return false;
}
// We only need to look for IEnumerable, because IEnumerable<T> extends it. public static bool AllowsNullValue([NotNull] Type type)
return typeof(IEnumerable).IsAssignableFrom(type); {
return !type.GetTypeInfo().IsValueType || IsNullableValueType(type);
}
public static TypeInfo ExtractGenericInterface([NotNull] Type queryType, Type interfaceType)
{
Func<TypeInfo, bool> matchesInterface =
typeInfo => typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == interfaceType;
var queryTypeInfo = queryType.GetTypeInfo();
if (matchesInterface(queryTypeInfo))
{
return queryTypeInfo;
}
else
{
return queryTypeInfo
.ImplementedInterfaces
.Select(type => type.GetTypeInfo())
.FirstOrDefault(matchesInterface);
}
} }
} }
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
@ -40,7 +41,8 @@ namespace Microsoft.AspNet.Mvc
/// </param> /// </param>
public BindAttribute([NotNull] Type predicateProviderType) public BindAttribute([NotNull] Type predicateProviderType)
{ {
if (!typeof(IPropertyBindingPredicateProvider).IsAssignableFrom(predicateProviderType)) if (!typeof(IPropertyBindingPredicateProvider).GetTypeInfo()
.IsAssignableFrom(predicateProviderType.GetTypeInfo()))
{ {
var message = Resources.FormatPropertyBindingPredicateProvider_WrongType( var message = Resources.FormatPropertyBindingPredicateProvider_WrongType(
predicateProviderType.FullName, predicateProviderType.FullName,

View File

@ -125,7 +125,7 @@ namespace Microsoft.AspNet.Mvc
} }
else else
{ {
value = parameterInfo.ParameterType.IsValueType() value = parameterInfo.ParameterType.GetTypeInfo().IsValueType
? Activator.CreateInstance(parameterInfo.ParameterType) ? Activator.CreateInstance(parameterInfo.ParameterType)
: null; : null;
} }

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.ModelBinding.Validation;
@ -116,7 +117,8 @@ namespace Microsoft.AspNet.Mvc.Core
// Unwrap potential Task<T> types. // Unwrap potential Task<T> types.
var actualReturnType = TypeHelper.GetTaskInnerTypeOrNull(declaredReturnType) ?? declaredReturnType; var actualReturnType = TypeHelper.GetTaskInnerTypeOrNull(declaredReturnType) ?? declaredReturnType;
if (actionReturnValue == null && typeof(IActionResult).IsAssignableFrom(actualReturnType)) if (actionReturnValue == null &&
typeof(IActionResult).GetTypeInfo().IsAssignableFrom(actualReturnType.GetTypeInfo()))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(
Resources.FormatActionResult_ActionReturnValueCannotBeNull(actualReturnType)); Resources.FormatActionResult_ActionReturnValueCannotBeNull(actualReturnType));

View File

@ -128,7 +128,7 @@ namespace Microsoft.AspNet.Mvc
if (propertyHelper.Property.CanWrite && propertyHelper.Property.SetMethod?.IsPublic == true) if (propertyHelper.Property.CanWrite && propertyHelper.Property.SetMethod?.IsPublic == true)
{ {
// Handle settable property. Do not set the property if the type is a non-nullable type. // Handle settable property. Do not set the property if the type is a non-nullable type.
if (source != null || propertyType.AllowsNullValue()) if (source != null || TypeHelper.AllowsNullValue(propertyType))
{ {
propertyHelper.SetValue(controller, source); propertyHelper.SetValue(controller, source);
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Core;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
@ -94,7 +95,7 @@ namespace Microsoft.AspNet.Mvc
[NotNull] Type filterType, [NotNull] Type filterType,
int order) int order)
{ {
if (!typeof(IFilter).IsAssignableFrom(filterType)) if (!typeof(IFilter).GetTypeInfo().IsAssignableFrom(filterType.GetTypeInfo()))
{ {
var message = Resources.FormatTypeMustDeriveFromType(filterType.FullName, typeof(IFilter).FullName); var message = Resources.FormatTypeMustDeriveFromType(filterType.FullName, typeof(IFilter).FullName);
throw new ArgumentException(message, nameof(filterType)); throw new ArgumentException(message, nameof(filterType));

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Reflection; using System.Reflection;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -30,7 +31,7 @@ namespace Microsoft.AspNet.Mvc
// With the following settings here, if a value is not present on the wire for value types // With the following settings here, if a value is not present on the wire for value types
// like primitive, struct etc., Json.net's serializer would throw exception which we catch // like primitive, struct etc., Json.net's serializer would throw exception which we catch
// and add it to model state. // and add it to model state.
if (propertyType.IsValueType() && !propertyType.IsNullableValueType()) if (propertyType.GetTypeInfo().IsValueType && !TypeHelper.IsNullableValueType(propertyType))
{ {
property.Required = Required.AllowNull; property.Required = Required.AllowNull;
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.JsonPatch; using Microsoft.AspNet.JsonPatch;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
@ -33,8 +34,9 @@ namespace Microsoft.AspNet.Mvc
/// <inheritdoc /> /// <inheritdoc />
public override bool CanRead(InputFormatterContext context) public override bool CanRead(InputFormatterContext context)
{ {
if (!typeof(IJsonPatchDocument).IsAssignableFrom(context.ModelType) || var modelTypeInfo = context.ModelType.GetTypeInfo();
!context.ModelType.IsGenericType()) if (!typeof(IJsonPatchDocument).GetTypeInfo().IsAssignableFrom(modelTypeInfo) ||
!modelTypeInfo.IsGenericType)
{ {
return false; return false;
} }

View File

@ -3,6 +3,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Http.Internal;
@ -29,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
if (request.HasFormContentType) if (request.HasFormContentType)
{ {
var form = await request.ReadFormAsync(); var form = await request.ReadFormAsync();
if (bindingContext.ModelType.IsAssignableFrom(form.GetType())) if (bindingContext.ModelType.GetTypeInfo().IsAssignableFrom(form.GetType().GetTypeInfo()))
{ {
model = form; model = form;
} }

View File

@ -69,10 +69,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private static Type GetKeyValuePairBinder(Type modelType) private static Type GetKeyValuePairBinder(Type modelType)
{ {
return ModelBindingHelper.GetPossibleBinderInstanceType( var modelTypeInfo = modelType.GetTypeInfo();
closedModelType: modelType, if (modelTypeInfo.IsGenericType &&
openModelType: typeof(KeyValuePair<,>), modelTypeInfo.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
openBinderType: typeof(KeyValuePairModelBinder<,>)); {
return typeof(KeyValuePairModelBinder<,>).MakeGenericType(modelTypeInfo.GenericTypeArguments);
}
return null;
} }
/// <remarks> /// <remarks>

View File

@ -94,13 +94,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
// IsEnum et cetera // IsEnum et cetera
var underlyingType = Nullable.GetUnderlyingType(context.Key.ModelType) ?? context.Key.ModelType; var underlyingType = Nullable.GetUnderlyingType(context.Key.ModelType) ?? context.Key.ModelType;
if (underlyingType.IsEnum()) var underlyingTypeInfo = underlyingType.GetTypeInfo();
if (underlyingTypeInfo.IsEnum)
{ {
// IsEnum // IsEnum
displayMetadata.IsEnum = true; displayMetadata.IsEnum = true;
// IsFlagsEnum // IsFlagsEnum
var underlyingTypeInfo = underlyingType.GetTypeInfo();
displayMetadata.IsFlagsEnum = displayMetadata.IsFlagsEnum =
underlyingTypeInfo.GetCustomAttribute<FlagsAttribute>(inherit: false) != null; underlyingTypeInfo.GetCustomAttribute<FlagsAttribute>(inherit: false) != null;

View File

@ -343,7 +343,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
} }
else else
{ {
_isRequired = !ModelType.AllowsNullValue(); _isRequired = !TypeHelper.AllowsNullValue(ModelType);
} }
} }

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
@ -126,7 +127,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
if (propertyHelper.Property.CanWrite && if (propertyHelper.Property.CanWrite &&
propertyHelper.Property.SetMethod?.IsPublic == true && propertyHelper.Property.SetMethod?.IsPublic == true &&
!key.ModelType.IsValueType()) !key.ModelType.GetTypeInfo().IsValueType)
{ {
propertyEntry.PropertySetter = propertyHelper.ValueSetter; propertyEntry.PropertySetter = propertyHelper.ValueSetter;
} }

View File

@ -511,7 +511,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return; return;
} }
if (value != null || property.PropertyType.AllowsNullValue()) if (value != null || TypeHelper.AllowsNullValue(property.PropertyType))
{ {
try try
{ {

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
ModelBindingHelper.ValidateBindingContext(bindingContext); ModelBindingHelper.ValidateBindingContext(bindingContext);
if (!TypeHelper.HasStringConverter(bindingContext.ModelType)) if (bindingContext.ModelMetadata.IsComplexType)
{ {
// this type cannot be converted // this type cannot be converted
return null; return null;

View File

@ -32,7 +32,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return null; // the value doesn't exist return null; // the value doesn't exist
} }
if (!context.ModelType.IsCompatibleWith(valueProviderResult.RawValue)) if (!TypeHelper.IsCompatibleWith(context.ModelType, valueProviderResult.RawValue))
{ {
return null; // value is of incompatible type return null; // value is of incompatible type
} }

View File

@ -6,6 +6,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
@ -313,7 +314,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
private static Type GetElementType(Type type) private static Type GetElementType(Type type)
{ {
Debug.Assert(typeof(IEnumerable).IsAssignableFrom(type)); Debug.Assert(typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()));
if (type.IsArray) if (type.IsArray)
{ {
return type.GetElementType(); return type.GetElementType();
@ -321,7 +322,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
foreach (var implementedInterface in type.GetInterfaces()) foreach (var implementedInterface in type.GetInterfaces())
{ {
if (implementedInterface.IsGenericType() && if (implementedInterface.GetTypeInfo().IsGenericType &&
implementedInterface.GetGenericTypeDefinition() == typeof(IEnumerable<>)) implementedInterface.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{ {
return implementedInterface.GetGenericArguments()[0]; return implementedInterface.GetGenericArguments()[0];

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Reflection;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.ModelBinding.Validation namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
@ -29,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
/// <inheritdoc /> /// <inheritdoc />
public bool IsTypeExcluded([NotNull] Type propertyType) public bool IsTypeExcluded([NotNull] Type propertyType)
{ {
return ExcludedType.IsAssignableFrom(propertyType); return ExcludedType.GetTypeInfo().IsAssignableFrom(propertyType.GetTypeInfo());
} }
} }
} }

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Reflection;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.ModelBinding.Validation namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
@ -44,7 +45,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
return true; return true;
} }
return CheckIfTypeNameMatches(type.BaseType()); return CheckIfTypeNameMatches(type.GetTypeInfo().BaseType);
} }
} }
} }

View File

@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
{ {
Type[] actualTypes; Type[] actualTypes;
if (type.IsGenericType() && if (type.GetTypeInfo().IsGenericType &&
type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)) type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
{ {
actualTypes = type.GenericTypeArguments; actualTypes = type.GenericTypeArguments;

View File

@ -413,7 +413,7 @@ namespace Microsoft.AspNet.Mvc
private static Type GetElementType(Type type) private static Type GetElementType(Type type)
{ {
Debug.Assert(typeof(IEnumerable).IsAssignableFrom(type)); Debug.Assert(typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()));
if (type.IsArray) if (type.IsArray)
{ {
return type.GetElementType(); return type.GetElementType();
@ -421,7 +421,7 @@ namespace Microsoft.AspNet.Mvc
foreach (var implementedInterface in type.GetInterfaces()) foreach (var implementedInterface in type.GetInterfaces())
{ {
if (implementedInterface.IsGenericType() && if (implementedInterface.GetTypeInfo().IsGenericType &&
implementedInterface.GetGenericTypeDefinition() == typeof(IEnumerable<>)) implementedInterface.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{ {
return implementedInterface.GetGenericArguments()[0]; return implementedInterface.GetGenericArguments()[0];
@ -473,14 +473,6 @@ namespace Microsoft.AspNet.Mvc
return (model is TModel) ? (TModel)model : default(TModel); return (model is TModel) ? (TModel)model : default(TModel);
} }
internal static Type GetPossibleBinderInstanceType(Type closedModelType,
Type openModelType,
Type openBinderType)
{
var typeArguments = TypeExtensions.GetTypeArgumentsIfMatch(closedModelType, openModelType);
return (typeArguments != null) ? openBinderType.MakeGenericType(typeArguments) : null;
}
internal static void ReplaceEmptyStringWithNull(ModelMetadata modelMetadata, ref object model) internal static void ReplaceEmptyStringWithNull(ModelMetadata modelMetadata, ref object model)
{ {
if (model is string && if (model is string &&

View File

@ -115,7 +115,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
typeInCollection = genericEnumerableType.GenericTypeArguments[0]; typeInCollection = genericEnumerableType.GenericTypeArguments[0];
} }
var typeInCollectionIsNullableValueType = typeInCollection.IsNullableValueType(); var typeInCollectionIsNullableValueType = TypeHelper.IsNullableValueType(typeInCollection);
var oldPrefix = htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix; var oldPrefix = htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix;

View File

@ -76,7 +76,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
typeInCollection = genericEnumerableType.GenericTypeArguments[0]; typeInCollection = genericEnumerableType.GenericTypeArguments[0];
} }
var typeInCollectionIsNullableValueType = typeInCollection.IsNullableValueType(); var typeInCollectionIsNullableValueType = TypeHelper.IsNullableValueType(typeInCollection);
var oldPrefix = viewData.TemplateInfo.HtmlFieldPrefix; var oldPrefix = viewData.TemplateInfo.HtmlFieldPrefix;
try try

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
@ -161,6 +162,8 @@ namespace Microsoft.AspNet.Mvc.Rendering.Internal
{ {
// Not returning type name here for IEnumerable<IFormFile> since we will be returning // Not returning type name here for IEnumerable<IFormFile> since we will be returning
// a more specific name, IEnumerableOfIFormFileName. // a more specific name, IEnumerableOfIFormFileName.
var fieldTypeInfo = fieldType.GetTypeInfo();
if (typeof(IEnumerable<IFormFile>) != fieldType) if (typeof(IEnumerable<IFormFile>) != fieldType)
{ {
yield return fieldType.Name; yield return fieldType.Name;
@ -174,7 +177,7 @@ namespace Microsoft.AspNet.Mvc.Rendering.Internal
else if (!modelMetadata.IsComplexType) else if (!modelMetadata.IsComplexType)
{ {
// IsEnum is false for the Enum class itself // IsEnum is false for the Enum class itself
if (fieldType.IsEnum()) if (fieldTypeInfo.IsEnum)
{ {
// Same as fieldType.BaseType.Name in this case // Same as fieldType.BaseType.Name in this case
yield return "Enum"; yield return "Enum";
@ -187,12 +190,12 @@ namespace Microsoft.AspNet.Mvc.Rendering.Internal
yield return "String"; yield return "String";
yield break; yield break;
} }
else if (!fieldType.IsInterface()) else if (!fieldTypeInfo.IsInterface)
{ {
var type = fieldType; var type = fieldType;
while (true) while (true)
{ {
type = type.BaseType(); type = type.GetTypeInfo().BaseType;
if (type == null || type == typeof(object)) if (type == null || type == typeof(object))
{ {
break; break;
@ -202,9 +205,9 @@ namespace Microsoft.AspNet.Mvc.Rendering.Internal
} }
} }
if (typeof(IEnumerable).IsAssignableFrom(fieldType)) if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(fieldTypeInfo))
{ {
if (typeof(IEnumerable<IFormFile>).IsAssignableFrom(fieldType)) if (typeof(IEnumerable<IFormFile>).GetTypeInfo().IsAssignableFrom(fieldTypeInfo))
{ {
yield return IEnumerableOfIFormFileName; yield return IEnumerableOfIFormFileName;
@ -217,7 +220,7 @@ namespace Microsoft.AspNet.Mvc.Rendering.Internal
yield return "Collection"; yield return "Collection";
} }
else if (typeof(IFormFile) != fieldType && typeof(IFormFile).IsAssignableFrom(fieldType)) else if (typeof(IFormFile) != fieldType && typeof(IFormFile).GetTypeInfo().IsAssignableFrom(fieldTypeInfo))
{ {
yield return nameof(IFormFile); yield return nameof(IFormFile);
} }

View File

@ -5,6 +5,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Reflection;
using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering.Expressions; using Microsoft.AspNet.Mvc.Rendering.Expressions;
@ -372,7 +373,7 @@ namespace Microsoft.AspNet.Mvc
{ {
// IsCompatibleObject verifies if the value is either an instance of _declaredModelType or (if value is // IsCompatibleObject verifies if the value is either an instance of _declaredModelType or (if value is
// null) that _declaredModelType is a nullable type. // null) that _declaredModelType is a nullable type.
var castWillSucceed = _declaredModelType.IsCompatibleWith(value); var castWillSucceed = TypeHelper.IsCompatibleWith(_declaredModelType, value);
if (!castWillSucceed) if (!castWillSucceed)
{ {
string message; string message;

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Reflection;
using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
@ -19,7 +20,7 @@ namespace Microsoft.AspNet.Mvc
/// <param name="type">The <see cref="IViewEngine"/> type that the descriptor represents.</param> /// <param name="type">The <see cref="IViewEngine"/> type that the descriptor represents.</param>
public ViewEngineDescriptor([NotNull] Type type) public ViewEngineDescriptor([NotNull] Type type)
{ {
if (!typeof(IViewEngine).IsAssignableFrom(type)) if (!typeof(IViewEngine).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))
{ {
var message = Resources.FormatTypeMustDeriveFromType(type.FullName, typeof(IViewEngine).FullName); var message = Resources.FormatTypeMustDeriveFromType(type.FullName, typeof(IViewEngine).FullName);
throw new ArgumentException(message, nameof(type)); throw new ArgumentException(message, nameof(type));

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq;
using Microsoft.AspNet.Mvc.Razor.Host; using Microsoft.AspNet.Mvc.Razor.Host;
using Microsoft.AspNet.Razor; using Microsoft.AspNet.Razor;
using Microsoft.AspNet.Razor.Generator; using Microsoft.AspNet.Razor.Generator;
@ -128,7 +129,7 @@ namespace Microsoft.AspNet.Mvc.Razor
.Substring(typeName.Length); .Substring(typeName.Length);
// ';' is optional // ';' is optional
propertyName = StringHelper.TrimSpacesAndChars(propertyName, ';'); propertyName = TrimSpacesAndChars(propertyName, ';');
Span.CodeGenerator = new InjectParameterGenerator(typeName.Trim(), propertyName); Span.CodeGenerator = new InjectParameterGenerator(typeName.Trim(), propertyName);
// Output the span and finish the block // Output the span and finish the block
@ -140,5 +141,54 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
return new ModelCodeGenerator(_baseType, model); return new ModelCodeGenerator(_baseType, model);
} }
// Internal for unit testing
internal static string TrimSpacesAndChars(string value, params char[] chars)
{
if (string.IsNullOrWhiteSpace(value))
{
return string.Empty;
}
if (chars == null || chars.Length == 0)
{
return value.Trim();
}
var firstIndex = 0;
for (; firstIndex < value.Length; firstIndex++)
{
var currentChar = value[firstIndex];
if (!char.IsWhiteSpace(currentChar) && !chars.Any(compareChar => compareChar == currentChar))
{
break;
}
}
// We trimmed all the way
if (firstIndex == value.Length)
{
return string.Empty;
}
var lastIndex = value.Length - 1;
for (; lastIndex > firstIndex; lastIndex--)
{
var currentChar = value[lastIndex];
if (!char.IsWhiteSpace(currentChar) && !chars.Any(compareChar => compareChar == currentChar))
{
break;
}
}
if (firstIndex == 0 && lastIndex == value.Length - 1)
{
return value;
}
else
{
return value.Substring(firstIndex, lastIndex - firstIndex + 1);
}
}
} }
} }

View File

@ -6,7 +6,6 @@
}, },
"dependencies": { "dependencies": {
"Microsoft.AspNet.FileProviders.Physical": "1.0.0-*", "Microsoft.AspNet.FileProviders.Physical": "1.0.0-*",
"Microsoft.AspNet.Mvc.Common": { "version": "6.0.0-*", "type": "build" },
"Microsoft.AspNet.Razor.Runtime": "4.0.0-*", "Microsoft.AspNet.Razor.Runtime": "4.0.0-*",
"Microsoft.Framework.Caching.Memory": "1.0.0-*", "Microsoft.Framework.Caching.Memory": "1.0.0-*",
"Microsoft.Framework.PropertyHelper.Sources": { "version": "1.0.0-*", "type": "build" }, "Microsoft.Framework.PropertyHelper.Sources": { "version": "1.0.0-*", "type": "build" },

View File

@ -12,6 +12,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Internal
public class SymbolsUtility public class SymbolsUtility
{ {
private const string SymWriterGuid = "0AE2DEB0-F901-478b-BB9F-881EE8066788"; private const string SymWriterGuid = "0AE2DEB0-F901-478b-BB9F-881EE8066788";
private static readonly Lazy<bool> _isMono = new Lazy<bool>(() => Type.GetType("Mono.Runtime") != null);
/// <summary> /// <summary>
/// Determines if the current platform supports symbols (pdb) generation. /// Determines if the current platform supports symbols (pdb) generation.
@ -19,7 +20,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Internal
/// <returns><c>true</c> if pdb generation is supported; <c>false</c> otherwise.</returns> /// <returns><c>true</c> if pdb generation is supported; <c>false</c> otherwise.</returns>
public static bool SupportsSymbolsGeneration() public static bool SupportsSymbolsGeneration()
{ {
if (PlatformHelper.IsMono) if (_isMono.Value)
{ {
return false; return false;
} }

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Razor.Runtime.TagHelpers; using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
@ -88,7 +89,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers.Internal
{ {
if (!context.AllAttributes.ContainsName(attribute) || if (!context.AllAttributes.ContainsName(attribute) ||
context.AllAttributes[attribute] == null || context.AllAttributes[attribute] == null ||
(typeof(string).IsAssignableFrom(context.AllAttributes[attribute].Value.GetType()) && (context.AllAttributes[attribute].Value is string &&
string.IsNullOrWhiteSpace(context.AllAttributes[attribute].Value as string))) string.IsNullOrWhiteSpace(context.AllAttributes[attribute].Value as string)))
{ {
// Missing attribute! // Missing attribute!

View File

@ -5,6 +5,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers; using Microsoft.AspNet.Razor.Runtime.TagHelpers;
@ -74,7 +75,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// "SelectExpressionNotEnumerable" InvalidOperationException during generation. // "SelectExpressionNotEnumerable" InvalidOperationException during generation.
// Metadata.IsCollectionType() is similar but does not take runtime type into account. // Metadata.IsCollectionType() is similar but does not take runtime type into account.
var realModelType = For.ModelExplorer.ModelType; var realModelType = For.ModelExplorer.ModelType;
var allowMultiple = typeof(string) != realModelType && typeof(IEnumerable).IsAssignableFrom(realModelType); var allowMultiple = typeof(string) != realModelType &&
typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(realModelType.GetTypeInfo());
// Ensure GenerateSelect() _never_ looks anything up in ViewData. // Ensure GenerateSelect() _never_ looks anything up in ViewData.
var items = Items ?? Enumerable.Empty<SelectListItem>(); var items = Items ?? Enumerable.Empty<SelectListItem>();

View File

@ -5,7 +5,6 @@
"warningsAsErrors": true "warningsAsErrors": true
}, },
"dependencies": { "dependencies": {
"Microsoft.AspNet.Mvc.Common": { "version": "6.0.0-*", "type": "build" },
"Microsoft.AspNet.Mvc.Razor": "6.0.0-*", "Microsoft.AspNet.Mvc.Razor": "6.0.0-*",
"Microsoft.Framework.Caching.Memory": "1.0.0-*", "Microsoft.Framework.Caching.Memory": "1.0.0-*",
"Microsoft.Framework.FileSystemGlobbing": "1.0.0-*", "Microsoft.Framework.FileSystemGlobbing": "1.0.0-*",

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Web.Http; using System.Web.Http;
using Microsoft.AspNet.Mvc.ApplicationModels; using Microsoft.AspNet.Mvc.ApplicationModels;
@ -27,7 +28,7 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{ {
// This has a binding behavior configured, just leave it alone. // This has a binding behavior configured, just leave it alone.
} }
else if (ValueProviderResult.CanConvertFromString(parameter.ParameterInfo.ParameterType)) else if (CanConvertFromString(parameter.ParameterInfo.ParameterType))
{ {
// Simple types are by-default from the URI. // Simple types are by-default from the URI.
parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo(); parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo();
@ -60,5 +61,12 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{ {
return controller.Attributes.OfType<IUseWebApiParameterConventions>().Any(); return controller.Attributes.OfType<IUseWebApiParameterConventions>().Any();
} }
private static bool CanConvertFromString(Type destinationType)
{
destinationType = Nullable.GetUnderlyingType(destinationType) ?? destinationType;
return TypeHelper.IsSimpleType(destinationType) ||
TypeDescriptor.GetConverter(destinationType).CanConvertFrom(typeof(string));
}
} }
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Net.Http.Formatting; using System.Net.Http.Formatting;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
@ -101,7 +102,7 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
if ((source.CanAcceptDataFrom(BindingSource.Path) || if ((source.CanAcceptDataFrom(BindingSource.Path) ||
source.CanAcceptDataFrom(BindingSource.Query)) && source.CanAcceptDataFrom(BindingSource.Query)) &&
ValueProviderResult.CanConvertFromString(parameter.ParameterType)) CanConvertFromString(parameter.ParameterType))
{ {
if (optionalParameters != null) if (optionalParameters != null)
{ {
@ -155,6 +156,13 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
return keys; return keys;
} }
private static bool CanConvertFromString(Type destinationType)
{
destinationType = Nullable.GetUnderlyingType(destinationType) ?? destinationType;
return TypeHelper.IsSimpleType(destinationType) ||
TypeDescriptor.GetConverter(destinationType).CanConvertFrom(typeof(string));
}
private class OverloadedParameter private class OverloadedParameter
{ {
public ParameterDescriptor ParameterDescriptor { get; set; } public ParameterDescriptor ParameterDescriptor { get; set; }

View File

@ -5,7 +5,7 @@
"warningsAsErrors": false "warningsAsErrors": false
}, },
"dependencies": { "dependencies": {
"Microsoft.AspNet.Mvc.Common": { "version": "6.0.0-*", "type": "build" }, "Microsoft.AspNet.Mvc.Common": { "type": "build", "version": "6.0.0-*" },
"Microsoft.AspNet.Mvc.Core": "6.0.0-*", "Microsoft.AspNet.Mvc.Core": "6.0.0-*",
"Microsoft.AspNet.WebApi.Client": "5.2.2", "Microsoft.AspNet.WebApi.Client": "5.2.2",
"Microsoft.Framework.PropertyHelper.Sources": { "version": "1.0.0-*", "type": "build" }, "Microsoft.Framework.PropertyHelper.Sources": { "version": "1.0.0-*", "type": "build" },

View File

@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc.Xml
var enumerableOfT = ClosedGenericMatcher.ExtractGenericInterface( var enumerableOfT = ClosedGenericMatcher.ExtractGenericInterface(
sourceEnumerableOfT, sourceEnumerableOfT,
typeof(IEnumerable<>)); typeof(IEnumerable<>));
if (!sourceEnumerableOfT.IsInterface() || enumerableOfT == null) if (!sourceEnumerableOfT.GetTypeInfo().IsInterface || enumerableOfT == null)
{ {
throw new ArgumentException( throw new ArgumentException(
Resources.FormatEnumerableWrapperProvider_InvalidSourceEnumerableOfT(typeof(IEnumerable<>).Name), Resources.FormatEnumerableWrapperProvider_InvalidSourceEnumerableOfT(typeof(IEnumerable<>).Name),

View File

@ -1,8 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.Xml namespace Microsoft.AspNet.Mvc.Xml
@ -37,10 +37,11 @@ namespace Microsoft.AspNet.Mvc.Xml
{ {
// Example: IEnumerable<SerializableError> // Example: IEnumerable<SerializableError>
var declaredType = context.DeclaredType; var declaredType = context.DeclaredType;
var declaredTypeInfo = declaredType.GetTypeInfo();
// We only wrap interfaces types(ex: IEnumerable<T>, IQueryable<T>, IList<T> etc.) and not // We only wrap interfaces types(ex: IEnumerable<T>, IQueryable<T>, IList<T> etc.) and not
// concrete types like List<T>, Collection<T> which implement IEnumerable<T>. // concrete types like List<T>, Collection<T> which implement IEnumerable<T>.
if (declaredType != null && declaredType.IsInterface() && declaredType.IsGenericType()) if (declaredType != null && declaredTypeInfo.IsInterface && declaredTypeInfo.IsGenericType)
{ {
var enumerableOfT = ClosedGenericMatcher.ExtractGenericInterface( var enumerableOfT = ClosedGenericMatcher.ExtractGenericInterface(
declaredType, declaredType,

View File

@ -87,7 +87,7 @@ namespace Microsoft.AspNet.Mvc.Xml
// is Dictionary<,> which implements IEnumerable<KeyValuePair<TKey, TValue>>) as the model // is Dictionary<,> which implements IEnumerable<KeyValuePair<TKey, TValue>>) as the model
// type here would be KeyValuePair<TKey, TValue> where Key and Value are public properties // type here would be KeyValuePair<TKey, TValue> where Key and Value are public properties
// which would also be probed for Required attribute validation. // which would also be probed for Required attribute validation.
if (modelType.IsGenericType()) if (modelType.GetTypeInfo().IsGenericType)
{ {
var enumerableOfT = ClosedGenericMatcher.ExtractGenericInterface(modelType, typeof(IEnumerable<>)); var enumerableOfT = ClosedGenericMatcher.ExtractGenericInterface(modelType, typeof(IEnumerable<>));
if (enumerableOfT != null) if (enumerableOfT != null)
@ -125,7 +125,7 @@ namespace Microsoft.AspNet.Mvc.Xml
// Since DefaultObjectValidator can handle Required attribute validation for reference types, // Since DefaultObjectValidator can handle Required attribute validation for reference types,
// we only consider value types here. // we only consider value types here.
if (propertyType.IsValueType() && !propertyType.IsNullableValueType()) if (propertyType.GetTypeInfo().IsValueType && !TypeHelper.IsNullableValueType(propertyType))
{ {
var validationError = GetValidationError(propertyInfo); var validationError = GetValidationError(propertyInfo);
if (validationError != null) if (validationError != null)

View File

@ -8,7 +8,6 @@
"Microsoft.AspNet.Authorization": "1.0.0-*", "Microsoft.AspNet.Authorization": "1.0.0-*",
"Microsoft.AspNet.Cors": "1.0.0-*", "Microsoft.AspNet.Cors": "1.0.0-*",
"Microsoft.AspNet.Mvc.ApiExplorer": "6.0.0-*", "Microsoft.AspNet.Mvc.ApiExplorer": "6.0.0-*",
"Microsoft.AspNet.Mvc.Common": { "version": "6.0.0-*", "type": "build" },
"Microsoft.AspNet.Mvc.Razor": "6.0.0-*", "Microsoft.AspNet.Mvc.Razor": "6.0.0-*",
"Microsoft.Framework.Caching.Memory": "1.0.0-*", "Microsoft.Framework.Caching.Memory": "1.0.0-*",
"Microsoft.Framework.DependencyInjection": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*",

View File

@ -1,97 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Xunit;
namespace Microsoft.AspNet.Mvc
{
public class StringHelperTest
{
public static TheoryData TrimSpacesAndCharsData
{
get
{
// input, trimCharacters, expectedOutput
return new TheoryData<string, char[], string>
{
{ "abcd", new char[] { }, "abcd" },
{ " /.", new char[] { '/', '.' }, string.Empty },
{ string.Empty, new char[] { }, string.Empty },
{ " ", new char[] { }, string.Empty },
{ " ", new char[] { }, string.Empty },
{ " / ", new char[] { '/' }, string.Empty },
{ " \t ", new char[] { '/' }, string.Empty },
{ " ", new char[] { '/' }, string.Empty },
{ " ", new char[] { '/' }, string.Empty },
{ "/", new char[] { '/' }, string.Empty },
{ "//", new char[] { '/' }, string.Empty },
{ "// ", new char[] { '/' }, string.Empty },
{ "/ ", new char[] { '/' }, string.Empty },
{ " a ", new char[] { }, "a" },
{ " a", new char[] { }, "a" },
{ "a ", new char[] { }, "a" },
{ " a ", new char[] { }, "a" },
{ " a \n\r", new char[] { }, "a" },
{ "\t\r a ", new char[] { }, "a" },
{ "\ta ", new char[] { }, "a" },
{ " a a ", new char[] { }, "a a" },
{ " a ", new char[] { '/' }, "a" },
{ " a", new char[] { '/' }, "a" },
{ "a ", new char[] { '/' }, "a" },
{ " a ", new char[] { '/' }, "a" },
{ " a \n\r", new char[] { '/' }, "a" },
{ "\t\r a ", new char[] { '/' }, "a" },
{ "\ta ", new char[] { '/' }, "a" },
{ " a a ", new char[] { '/' }, "a a" },
{ " a ", new char[] { '/', ' ' }, "a" },
{ " a", new char[] { '/', ' ' }, "a" },
{ "a ", new char[] { '/', ' ' }, "a" },
{ " a ", new char[] { '/', ' ' }, "a" },
{ " a \n\r", new char[] { '/', ' ' }, "a" },
{ "\t\r a ", new char[] { '/', ' ' }, "a" },
{ "\ta ", new char[] { '/', ' ' }, "a" },
{ " a a ", new char[] { '/', ' ' }, "a a" },
{ "/ a ", new char[] { '/' }, "a" },
{ " / a", new char[] { '/' }, "a" },
{ "a / /", new char[] { '/' }, "a" },
{ " a // //", new char[] { '/' }, "a" },
{ " a \n\r//", new char[] { '/' }, "a" },
{ "////\t\r a ", new char[] { '/' }, "a" },
{ "\ta /", new char[] { '/' }, "a" },
{ " a/ a ", new char[] { '/' }, "a/ a" },
{ "/ a ", new char[] { '/', ' ' }, "a" },
{ " / a", new char[] { '/', ' ' }, "a" },
{ "a / /", new char[] { '/', ' ' }, "a" },
{ " a // //", new char[] { '/', ' ' }, "a" },
{ " a \n\r//", new char[] { '/', ' ' }, "a" },
{ "////\t\r a ", new char[] { '/', ' ' }, "a" },
{ "\ta /", new char[] { '/', ' ' }, "a" },
{ " a/ a ", new char[] { '/', ' ' }, "a/ a" },
{ " a /.", new char[] { '/', '.' }, "a" },
{ " a", new char[] { '/', '.' }, "a" },
{ "/. ./a ", new char[] { '/', '.' }, "a" },
{ " a ", new char[] { '/', '.' }, "a" },
{ " a \n\r", new char[] { '/', '.' }, "a" },
{ "\t\r a ", new char[] { '/', '.' }, "a" },
{ "\ta ", new char[] { '/', '.' }, "a" },
{ "///..a/./a /. ./....", new char[] { '/', '.' }, "a/./a" },
};
}
}
[Theory]
[MemberData(nameof(TrimSpacesAndCharsData))]
public void TrimSpacesAndChars_GeneratesExpectedOutput(
string input,
char[] trimCharacters,
string expectedOutput)
{
// Arrange & Act
var output = StringHelper.TrimSpacesAndChars(input, trimCharacters);
// Assert
Assert.Equal(expectedOutput, output, StringComparer.Ordinal);
}
}
}

View File

@ -7,7 +7,7 @@ using Xunit;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public class TypeExtensionsTest public class TypeHelperTests
{ {
[Theory] [Theory]
[InlineData(typeof(decimal))] [InlineData(typeof(decimal))]
@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Mvc
public void IsCompatibleWithReturnsFalse_IfValueTypeIsNull(Type type) public void IsCompatibleWithReturnsFalse_IfValueTypeIsNull(Type type)
{ {
// Act // Act
bool result = TypeExtensions.IsCompatibleWith(type, value: null); bool result = TypeHelper.IsCompatibleWith(type, value: null);
// Assert // Assert
Assert.False(result); Assert.False(result);
@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Mvc
public void IsCompatibleWithReturnsFalse_IfValueIsMismatched(Type type) public void IsCompatibleWithReturnsFalse_IfValueIsMismatched(Type type)
{ {
// Act // Act
bool result = TypeExtensions.IsCompatibleWith(type, value: "Hello world"); bool result = TypeHelper.IsCompatibleWith(type, value: "Hello world");
// Assert // Assert
Assert.False(result); Assert.False(result);
@ -56,7 +56,7 @@ namespace Microsoft.AspNet.Mvc
public void IsCompatibleWithReturnsTrue_IfValueIsAssignable(Type type, object value) public void IsCompatibleWithReturnsTrue_IfValueIsAssignable(Type type, object value)
{ {
// Act // Act
bool result = TypeExtensions.IsCompatibleWith(type, value); bool result = TypeHelper.IsCompatibleWith(type, value);
// Assert // Assert
Assert.True(result); Assert.True(result);

View File

@ -9,6 +9,7 @@ using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing;
using Microsoft.AspNet.Testing;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using Moq; using Moq;
using Xunit; using Xunit;
@ -90,7 +91,7 @@ namespace Microsoft.AspNet.Mvc
{ {
yield return new object[] { 30, 0 }; yield return new object[] { 30, 0 };
if (PlatformHelper.IsMono) if (TestPlatformHelper.IsMono)
{ {
// The StreamWriter in Mono buffers 2x the buffer size before flushing. // The StreamWriter in Mono buffers 2x the buffer size before flushing.
yield return new object[] { ViewResultStreamWriterBufferSize * 2 + 30, ViewResultStreamWriterBufferSize }; yield return new object[] { ViewResultStreamWriterBufferSize * 2 + 30, ViewResultStreamWriterBufferSize };

View File

@ -177,6 +177,92 @@ namespace Microsoft.AspNet.Mvc.Razor
} }
} }
public static TheoryData TrimSpacesAndCharsData
{
get
{
// input, trimCharacters, expectedOutput
return new TheoryData<string, char[], string>
{
{ "abcd", new char[] { }, "abcd" },
{ " /.", new char[] { '/', '.' }, string.Empty },
{ string.Empty, new char[] { }, string.Empty },
{ " ", new char[] { }, string.Empty },
{ " ", new char[] { }, string.Empty },
{ " / ", new char[] { '/' }, string.Empty },
{ " \t ", new char[] { '/' }, string.Empty },
{ " ", new char[] { '/' }, string.Empty },
{ " ", new char[] { '/' }, string.Empty },
{ "/", new char[] { '/' }, string.Empty },
{ "//", new char[] { '/' }, string.Empty },
{ "// ", new char[] { '/' }, string.Empty },
{ "/ ", new char[] { '/' }, string.Empty },
{ " a ", new char[] { }, "a" },
{ " a", new char[] { }, "a" },
{ "a ", new char[] { }, "a" },
{ " a ", new char[] { }, "a" },
{ " a \n\r", new char[] { }, "a" },
{ "\t\r a ", new char[] { }, "a" },
{ "\ta ", new char[] { }, "a" },
{ " a a ", new char[] { }, "a a" },
{ " a ", new char[] { '/' }, "a" },
{ " a", new char[] { '/' }, "a" },
{ "a ", new char[] { '/' }, "a" },
{ " a ", new char[] { '/' }, "a" },
{ " a \n\r", new char[] { '/' }, "a" },
{ "\t\r a ", new char[] { '/' }, "a" },
{ "\ta ", new char[] { '/' }, "a" },
{ " a a ", new char[] { '/' }, "a a" },
{ " a ", new char[] { '/', ' ' }, "a" },
{ " a", new char[] { '/', ' ' }, "a" },
{ "a ", new char[] { '/', ' ' }, "a" },
{ " a ", new char[] { '/', ' ' }, "a" },
{ " a \n\r", new char[] { '/', ' ' }, "a" },
{ "\t\r a ", new char[] { '/', ' ' }, "a" },
{ "\ta ", new char[] { '/', ' ' }, "a" },
{ " a a ", new char[] { '/', ' ' }, "a a" },
{ "/ a ", new char[] { '/' }, "a" },
{ " / a", new char[] { '/' }, "a" },
{ "a / /", new char[] { '/' }, "a" },
{ " a // //", new char[] { '/' }, "a" },
{ " a \n\r//", new char[] { '/' }, "a" },
{ "////\t\r a ", new char[] { '/' }, "a" },
{ "\ta /", new char[] { '/' }, "a" },
{ " a/ a ", new char[] { '/' }, "a/ a" },
{ "/ a ", new char[] { '/', ' ' }, "a" },
{ " / a", new char[] { '/', ' ' }, "a" },
{ "a / /", new char[] { '/', ' ' }, "a" },
{ " a // //", new char[] { '/', ' ' }, "a" },
{ " a \n\r//", new char[] { '/', ' ' }, "a" },
{ "////\t\r a ", new char[] { '/', ' ' }, "a" },
{ "\ta /", new char[] { '/', ' ' }, "a" },
{ " a/ a ", new char[] { '/', ' ' }, "a/ a" },
{ " a /.", new char[] { '/', '.' }, "a" },
{ " a", new char[] { '/', '.' }, "a" },
{ "/. ./a ", new char[] { '/', '.' }, "a" },
{ " a ", new char[] { '/', '.' }, "a" },
{ " a \n\r", new char[] { '/', '.' }, "a" },
{ "\t\r a ", new char[] { '/', '.' }, "a" },
{ "\ta ", new char[] { '/', '.' }, "a" },
{ "///..a/./a /. ./....", new char[] { '/', '.' }, "a/./a" },
};
}
}
[Theory]
[MemberData(nameof(TrimSpacesAndCharsData))]
public void TrimSpacesAndChars_GeneratesExpectedOutput(
string input,
char[] trimCharacters,
string expectedOutput)
{
// Arrange & Act
var output = MvcRazorCodeParser.TrimSpacesAndChars(input, trimCharacters);
// Assert
Assert.Equal(expectedOutput, output, StringComparer.Ordinal);
}
private static CodeTree CreateCodeTree(params Chunk[] chunks) private static CodeTree CreateCodeTree(params Chunk[] chunks)
{ {
return new CodeTree return new CodeTree