From f889965929dad61f751767a41361aa6d86b33b62 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Fri, 26 Feb 2016 21:28:15 -0800 Subject: [PATCH] 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 --- .../ModelBinding/ModelMetadata.cs | 2 +- .../DefaultApiDescriptionProvider.cs | 11 +++---- .../BindAttribute.cs | 5 ++-- .../Filters/FilterCollection.cs | 4 ++- .../Internal/ControllerActionInvoker.cs | 4 ++- .../ModelBinding/KeyValuePairModelBinder.cs | 9 +++--- .../ModelBinding/ModelBindingHelper.cs | 30 ------------------- .../Validation/ValidationExcludeFilter.cs | 2 +- .../Properties/Resources.Designer.cs | 16 ---------- .../Resources.resx | 3 -- .../SelectTagHelper.cs | 4 ++- .../DefaultViewComponentInvoker.cs | 2 +- .../ViewFeatures/TemplateRenderer.cs | 6 ++-- .../ContentNegotiator/FormattingUtilities.cs | 2 +- 14 files changed, 30 insertions(+), 70 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelMetadata.cs b/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelMetadata.cs index c21f6489c0..53c0b827d7 100644 --- a/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelMetadata.cs +++ b/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelMetadata.cs @@ -406,7 +406,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(ModelType, typeof(IEnumerable<>)); ElementType = enumerableType?.GenericTypeArguments[0]; - if (ElementType == null && typeof(IEnumerable).IsAssignableFrom(ModelType)) + if (ElementType == null) { // ModelType implements IEnumerable but not IEnumerable. ElementType = typeof(object); diff --git a/src/Microsoft.AspNetCore.Mvc.ApiExplorer/DefaultApiDescriptionProvider.cs b/src/Microsoft.AspNetCore.Mvc.ApiExplorer/DefaultApiDescriptionProvider.cs index 8215cfe67a..5deb746f94 100644 --- a/src/Microsoft.AspNetCore.Mvc.ApiExplorer/DefaultApiDescriptionProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.ApiExplorer/DefaultApiDescriptionProvider.cs @@ -4,10 +4,11 @@ using System; using System.Collections.Generic; using System.Linq; +#if DOTNET5_4 using System.Reflection; +#endif using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; -using Microsoft.AspNetCore.Mvc.ActionConstraints; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Internal; @@ -135,9 +136,9 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer apiDescription.SupportedResponseFormats.Add(format); } } - + // It would be possible here to configure an action with multiple body parameters, in which case you - // could end up with duplicate data. + // could end up with duplicate data. foreach (var parameter in apiDescription.ParameterDescriptions.Where(p => p.Source == BindingSource.Body)) { var formats = GetRequestFormats(action, requestMetadataAttributes, parameter.Type); @@ -427,7 +428,7 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer // If the method is declared to return IActionResult or a derived class, that information // isn't valuable to the formatter. - if (typeof(IActionResult).GetTypeInfo().IsAssignableFrom(unwrappedType.GetTypeInfo())) + if (typeof(IActionResult).IsAssignableFrom(unwrappedType)) { return null; } @@ -577,7 +578,7 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer public ParameterDescriptor Parameter { get; } - // Avoid infinite recursion by tracking properties. + // Avoid infinite recursion by tracking properties. private HashSet Visited { get; } public void WalkParameter(ApiParameterDescriptionContext context) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/BindAttribute.cs b/src/Microsoft.AspNetCore.Mvc.Core/BindAttribute.cs index a1c2ecc190..0c2cfc4059 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/BindAttribute.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/BindAttribute.cs @@ -4,7 +4,9 @@ using System; using System.Collections.Generic; using System.Linq; +#if DOTNET5_4 using System.Reflection; +#endif using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.DependencyInjection; @@ -52,8 +54,7 @@ namespace Microsoft.AspNetCore.Mvc throw new ArgumentNullException(nameof(predicateProviderType)); } - if (!typeof(IPropertyBindingPredicateProvider).GetTypeInfo() - .IsAssignableFrom(predicateProviderType.GetTypeInfo())) + if (!typeof(IPropertyBindingPredicateProvider).IsAssignableFrom(predicateProviderType)) { var message = Resources.FormatPropertyBindingPredicateProvider_WrongType( predicateProviderType.FullName, diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Filters/FilterCollection.cs b/src/Microsoft.AspNetCore.Mvc.Core/Filters/FilterCollection.cs index 23290b0a0d..3f7d5fb97c 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Filters/FilterCollection.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Filters/FilterCollection.cs @@ -3,7 +3,9 @@ using System; using System.Collections.ObjectModel; +#if DOTNET5_4 using System.Reflection; +#endif using Microsoft.AspNetCore.Mvc.Core; namespace Microsoft.AspNetCore.Mvc.Filters @@ -99,7 +101,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters throw new ArgumentNullException(nameof(filterType)); } - if (!typeof(IFilterMetadata).GetTypeInfo().IsAssignableFrom(filterType.GetTypeInfo())) + if (!typeof(IFilterMetadata).IsAssignableFrom(filterType)) { var message = Resources.FormatTypeMustDeriveFromType( filterType.FullName, diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerActionInvoker.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerActionInvoker.cs index 242ee715be..2cf6f425f0 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerActionInvoker.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerActionInvoker.cs @@ -4,7 +4,9 @@ using System; using System.Collections.Generic; using System.Diagnostics; +#if DOTNET5_4 using System.Reflection; +#endif using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Core; @@ -143,7 +145,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Unwrap potential Task types. var actualReturnType = GetTaskInnerTypeOrNull(declaredReturnType) ?? declaredReturnType; if (actionReturnValue == null && - typeof(IActionResult).GetTypeInfo().IsAssignableFrom(actualReturnType.GetTypeInfo())) + typeof(IActionResult).IsAssignableFrom(actualReturnType)) { throw new InvalidOperationException( Resources.FormatActionResult_ActionReturnValueCannotBeNull(actualReturnType)); diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/KeyValuePairModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/KeyValuePairModelBinder.cs index 42719e10a6..7f6122089c 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/KeyValuePairModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/KeyValuePairModelBinder.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Threading.Tasks; namespace Microsoft.AspNetCore.Mvc.ModelBinding @@ -17,9 +16,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding throw new ArgumentNullException(nameof(bindingContext)); } - ModelBindingHelper.ValidateBindingContext(bindingContext, - typeof(KeyValuePair), - allowNullModel: true); + if (bindingContext.ModelType != typeof(KeyValuePair)) + { + // This binder does not apply. + return; + } var keyResult = await TryBindStrongModel(bindingContext, "Key"); var valueResult = await TryBindStrongModel(bindingContext, "Value"); diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ModelBindingHelper.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ModelBindingHelper.cs index 6c699515a6..1ba5650f31 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ModelBindingHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ModelBindingHelper.cs @@ -13,7 +13,6 @@ using System.Runtime.ExceptionServices; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.Formatters; -using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; 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(object model) { return (model is TModel) ? (TModel)model : default(TModel); diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Validation/ValidationExcludeFilter.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Validation/ValidationExcludeFilter.cs index 62799061cf..16b560dba3 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Validation/ValidationExcludeFilter.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Validation/ValidationExcludeFilter.cs @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation if (Type != null) { - if (Type.GetTypeInfo().IsAssignableFrom(context.Key.ModelType.GetTypeInfo())) + if (Type.IsAssignableFrom(context.Key.ModelType)) { context.ValidationMetadata.ValidateChildren = false; } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs index 55a474f187..7928fadd7b 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs @@ -906,22 +906,6 @@ namespace Microsoft.AspNetCore.Mvc.Core return GetString("ModelBinderUtil_ModelMetadataCannotBeNull"); } - /// - /// The binding context has a ModelType of '{0}', but this binder can only operate on models of type '{1}'. - /// - internal static string ModelBinderUtil_ModelTypeIsWrong - { - get { return GetString("ModelBinderUtil_ModelTypeIsWrong"); } - } - - /// - /// The binding context has a ModelType of '{0}', but this binder can only operate on models of type '{1}'. - /// - internal static string FormatModelBinderUtil_ModelTypeIsWrong(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("ModelBinderUtil_ModelTypeIsWrong"), p0, p1); - } - /// /// A value for the '{0}' property was not provided. /// diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx b/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx index 04dc1391b1..e6494c6569 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx +++ b/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx @@ -294,9 +294,6 @@ The binding context cannot have a null ModelMetadata. - - The binding context has a ModelType of '{0}', but this binder can only operate on models of type '{1}'. - A value for the '{0}' property was not provided. diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/SelectTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/SelectTagHelper.cs index f650216b72..fc861d22fa 100644 --- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/SelectTagHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/SelectTagHelper.cs @@ -5,7 +5,9 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +#if DOTNET5_6 using System.Reflection; +#endif using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.Rendering; 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. var realModelType = For.ModelExplorer.ModelType; _allowMultiple = typeof(string) != realModelType && - typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(realModelType.GetTypeInfo()); + typeof(IEnumerable).IsAssignableFrom(realModelType); _currentValues = Generator.GetCurrentValues( ViewContext, For.ModelExplorer, diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentInvoker.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentInvoker.cs index bde18ca400..ff9dcfdbbc 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentInvoker.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentInvoker.cs @@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents nameof(ViewComponentDescriptor))); } - var isAsync = typeof(Task).GetTypeInfo().IsAssignableFrom(methodInfo.ReturnType.GetTypeInfo()); + var isAsync = typeof(Task).IsAssignableFrom(methodInfo.ReturnType); IViewComponentResult result; if (isAsync) { diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/TemplateRenderer.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/TemplateRenderer.cs index dd2d1480ad..ed9c904de5 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/TemplateRenderer.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/TemplateRenderer.cs @@ -228,9 +228,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal } } - if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(fieldTypeInfo)) + if (typeof(IEnumerable).IsAssignableFrom(fieldType)) { - if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(fieldTypeInfo)) + if (typeof(IEnumerable).IsAssignableFrom(fieldType)) { yield return IEnumerableOfIFormFileName; @@ -243,7 +243,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal 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); } diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormattingUtilities.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormattingUtilities.cs index 5e0e775f8e..d2536ded1c 100644 --- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormattingUtilities.cs +++ b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormattingUtilities.cs @@ -124,7 +124,7 @@ namespace System.Net.Http /// public static bool IsJTokenType(Type type) { - return typeof(JToken).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()); + return typeof(JToken).IsAssignableFrom(type); } ///