Simplify `IsAssignableFrom()` use

- standardize on the `Type` extension method; less verbiage
- `ModelMetadata` had a redundant `IsAssignableFrom()` call
- `ModelBindingHelper.ValidateBindingContext()` over-engineered and used just once
 - do useful bit inline in `KeyValuePairModelBinder` but now a silent "does not apply" case
This commit is contained in:
Doug Bunting 2016-02-26 21:28:15 -08:00
parent 1e5b0b9bec
commit f889965929
14 changed files with 30 additions and 70 deletions

View File

@ -406,7 +406,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(ModelType, typeof(IEnumerable<>)); var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(ModelType, typeof(IEnumerable<>));
ElementType = enumerableType?.GenericTypeArguments[0]; ElementType = enumerableType?.GenericTypeArguments[0];
if (ElementType == null && typeof(IEnumerable).IsAssignableFrom(ModelType)) if (ElementType == null)
{ {
// ModelType implements IEnumerable but not IEnumerable<T>. // ModelType implements IEnumerable but not IEnumerable<T>.
ElementType = typeof(object); ElementType = typeof(object);

View File

@ -4,10 +4,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
#if DOTNET5_4
using System.Reflection; using System.Reflection;
#endif
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.Internal;
@ -427,7 +428,7 @@ namespace Microsoft.AspNetCore.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).GetTypeInfo().IsAssignableFrom(unwrappedType.GetTypeInfo())) if (typeof(IActionResult).IsAssignableFrom(unwrappedType))
{ {
return null; return null;
} }

View File

@ -4,7 +4,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
#if DOTNET5_4
using System.Reflection; using System.Reflection;
#endif
using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -52,8 +54,7 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(predicateProviderType)); throw new ArgumentNullException(nameof(predicateProviderType));
} }
if (!typeof(IPropertyBindingPredicateProvider).GetTypeInfo() if (!typeof(IPropertyBindingPredicateProvider).IsAssignableFrom(predicateProviderType))
.IsAssignableFrom(predicateProviderType.GetTypeInfo()))
{ {
var message = Resources.FormatPropertyBindingPredicateProvider_WrongType( var message = Resources.FormatPropertyBindingPredicateProvider_WrongType(
predicateProviderType.FullName, predicateProviderType.FullName,

View File

@ -3,7 +3,9 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
#if DOTNET5_4
using System.Reflection; using System.Reflection;
#endif
using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.Core;
namespace Microsoft.AspNetCore.Mvc.Filters namespace Microsoft.AspNetCore.Mvc.Filters
@ -99,7 +101,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters
throw new ArgumentNullException(nameof(filterType)); throw new ArgumentNullException(nameof(filterType));
} }
if (!typeof(IFilterMetadata).GetTypeInfo().IsAssignableFrom(filterType.GetTypeInfo())) if (!typeof(IFilterMetadata).IsAssignableFrom(filterType))
{ {
var message = Resources.FormatTypeMustDeriveFromType( var message = Resources.FormatTypeMustDeriveFromType(
filterType.FullName, filterType.FullName,

View File

@ -4,7 +4,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
#if DOTNET5_4
using System.Reflection; using System.Reflection;
#endif
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.Core;
@ -143,7 +145,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
// Unwrap potential Task<T> types. // Unwrap potential Task<T> types.
var actualReturnType = GetTaskInnerTypeOrNull(declaredReturnType) ?? declaredReturnType; var actualReturnType = GetTaskInnerTypeOrNull(declaredReturnType) ?? declaredReturnType;
if (actionReturnValue == null && if (actionReturnValue == null &&
typeof(IActionResult).GetTypeInfo().IsAssignableFrom(actualReturnType.GetTypeInfo())) typeof(IActionResult).IsAssignableFrom(actualReturnType))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(
Resources.FormatActionResult_ActionReturnValueCannotBeNull(actualReturnType)); Resources.FormatActionResult_ActionReturnValueCannotBeNull(actualReturnType));

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
@ -17,9 +16,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
throw new ArgumentNullException(nameof(bindingContext)); throw new ArgumentNullException(nameof(bindingContext));
} }
ModelBindingHelper.ValidateBindingContext(bindingContext, if (bindingContext.ModelType != typeof(KeyValuePair<TKey, TValue>))
typeof(KeyValuePair<TKey, TValue>), {
allowNullModel: true); // This binder does not apply.
return;
}
var keyResult = await TryBindStrongModel<TKey>(bindingContext, "Key"); var keyResult = await TryBindStrongModel<TKey>(bindingContext, "Key");
var valueResult = await TryBindStrongModel<TValue>(bindingContext, "Value"); var valueResult = await TryBindStrongModel<TValue>(bindingContext, "Value");

View File

@ -13,7 +13,6 @@ using System.Runtime.ExceptionServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
@ -744,35 +743,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
} }
} }
internal static void ValidateBindingContext(
ModelBindingContext bindingContext,
Type requiredType,
bool allowNullModel)
{
ValidateBindingContext(bindingContext);
if (bindingContext.ModelType != requiredType)
{
var message = Resources.FormatModelBinderUtil_ModelTypeIsWrong(bindingContext.ModelType, requiredType);
throw new ArgumentException(message, nameof(bindingContext));
}
if (!allowNullModel && bindingContext.Model == null)
{
var message = Resources.FormatModelBinderUtil_ModelCannotBeNull(requiredType);
throw new ArgumentException(message, nameof(bindingContext));
}
if (bindingContext.Model != null &&
!bindingContext.ModelType.GetTypeInfo().IsAssignableFrom(requiredType.GetTypeInfo()))
{
var message = Resources.FormatModelBinderUtil_ModelInstanceIsWrong(
bindingContext.Model.GetType(),
requiredType);
throw new ArgumentException(message, nameof(bindingContext));
}
}
internal static TModel CastOrDefault<TModel>(object model) internal static TModel CastOrDefault<TModel>(object model)
{ {
return (model is TModel) ? (TModel)model : default(TModel); return (model is TModel) ? (TModel)model : default(TModel);

View File

@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation
if (Type != null) if (Type != null)
{ {
if (Type.GetTypeInfo().IsAssignableFrom(context.Key.ModelType.GetTypeInfo())) if (Type.IsAssignableFrom(context.Key.ModelType))
{ {
context.ValidationMetadata.ValidateChildren = false; context.ValidationMetadata.ValidateChildren = false;
} }

View File

@ -906,22 +906,6 @@ namespace Microsoft.AspNetCore.Mvc.Core
return GetString("ModelBinderUtil_ModelMetadataCannotBeNull"); return GetString("ModelBinderUtil_ModelMetadataCannotBeNull");
} }
/// <summary>
/// The binding context has a ModelType of '{0}', but this binder can only operate on models of type '{1}'.
/// </summary>
internal static string ModelBinderUtil_ModelTypeIsWrong
{
get { return GetString("ModelBinderUtil_ModelTypeIsWrong"); }
}
/// <summary>
/// The binding context has a ModelType of '{0}', but this binder can only operate on models of type '{1}'.
/// </summary>
internal static string FormatModelBinderUtil_ModelTypeIsWrong(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ModelBinderUtil_ModelTypeIsWrong"), p0, p1);
}
/// <summary> /// <summary>
/// A value for the '{0}' property was not provided. /// A value for the '{0}' property was not provided.
/// </summary> /// </summary>

View File

@ -294,9 +294,6 @@
<data name="ModelBinderUtil_ModelMetadataCannotBeNull" xml:space="preserve"> <data name="ModelBinderUtil_ModelMetadataCannotBeNull" xml:space="preserve">
<value>The binding context cannot have a null ModelMetadata.</value> <value>The binding context cannot have a null ModelMetadata.</value>
</data> </data>
<data name="ModelBinderUtil_ModelTypeIsWrong" xml:space="preserve">
<value>The binding context has a ModelType of '{0}', but this binder can only operate on models of type '{1}'.</value>
</data>
<data name="ModelBinding_MissingBindRequiredMember" xml:space="preserve"> <data name="ModelBinding_MissingBindRequiredMember" xml:space="preserve">
<value>A value for the '{0}' property was not provided.</value> <value>A value for the '{0}' property was not provided.</value>
</data> </data>

View File

@ -5,7 +5,9 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
#if DOTNET5_6
using System.Reflection; using System.Reflection;
#endif
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.TagHelpers.Internal; using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
@ -95,7 +97,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
// Metadata.IsEnumerableType is similar but does not take runtime type into account. // Metadata.IsEnumerableType is similar but does not take runtime type into account.
var realModelType = For.ModelExplorer.ModelType; var realModelType = For.ModelExplorer.ModelType;
_allowMultiple = typeof(string) != realModelType && _allowMultiple = typeof(string) != realModelType &&
typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(realModelType.GetTypeInfo()); typeof(IEnumerable).IsAssignableFrom(realModelType);
_currentValues = Generator.GetCurrentValues( _currentValues = Generator.GetCurrentValues(
ViewContext, ViewContext,
For.ModelExplorer, For.ModelExplorer,

View File

@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
nameof(ViewComponentDescriptor))); nameof(ViewComponentDescriptor)));
} }
var isAsync = typeof(Task).GetTypeInfo().IsAssignableFrom(methodInfo.ReturnType.GetTypeInfo()); var isAsync = typeof(Task).IsAssignableFrom(methodInfo.ReturnType);
IViewComponentResult result; IViewComponentResult result;
if (isAsync) if (isAsync)
{ {

View File

@ -228,9 +228,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
} }
} }
if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(fieldTypeInfo)) if (typeof(IEnumerable).IsAssignableFrom(fieldType))
{ {
if (typeof(IEnumerable<IFormFile>).GetTypeInfo().IsAssignableFrom(fieldTypeInfo)) if (typeof(IEnumerable<IFormFile>).IsAssignableFrom(fieldType))
{ {
yield return IEnumerableOfIFormFileName; yield return IEnumerableOfIFormFileName;
@ -243,7 +243,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
yield return "Collection"; yield return "Collection";
} }
else if (typeof(IFormFile) != fieldType && typeof(IFormFile).GetTypeInfo().IsAssignableFrom(fieldTypeInfo)) else if (typeof(IFormFile) != fieldType && typeof(IFormFile).IsAssignableFrom(fieldType))
{ {
yield return nameof(IFormFile); yield return nameof(IFormFile);
} }

View File

@ -124,7 +124,7 @@ namespace System.Net.Http
/// </returns> /// </returns>
public static bool IsJTokenType(Type type) public static bool IsJTokenType(Type type)
{ {
return typeof(JToken).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()); return typeof(JToken).IsAssignableFrom(type);
} }
/// <summary> /// <summary>