From 576c0e6a654ae67ab77bfec1e9f9c412cb30427e Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Tue, 8 Nov 2016 14:16:03 -0800 Subject: [PATCH] Throw an exception if configurationType to CreateConfigureDelegate is abstract/has no parameterless ctor Addresses #5431 --- .../MiddlewareFilterConfigurationProvider.cs | 11 ++++++++ .../Properties/Resources.Designer.cs | 16 +++++++++++ .../Resources.resx | 4 +++ ...ddlewareFilterConfigurationProviderTest.cs | 27 +++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MiddlewareFilterConfigurationProvider.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MiddlewareFilterConfigurationProvider.cs index 49d8e52d95..ca05f4d6df 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MiddlewareFilterConfigurationProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MiddlewareFilterConfigurationProvider.cs @@ -23,6 +23,12 @@ namespace Microsoft.AspNetCore.Mvc.Internal throw new ArgumentNullException(nameof(configurationType)); } + if (!HasParameterlessConstructor(configurationType.GetTypeInfo())) + { + throw new InvalidOperationException( + Resources.FormatMiddlewareFilterConfigurationProvider_CreateConfigureDelegate_CannotCreateType(configurationType, nameof(configurationType))); + } + var instance = Activator.CreateInstance(configurationType); var configureDelegateBuilder = GetConfigureDelegateBuilder(configurationType); return configureDelegateBuilder.Build(instance); @@ -66,6 +72,11 @@ namespace Microsoft.AspNetCore.Mvc.Internal return methodInfo; } + private static bool HasParameterlessConstructor(TypeInfo modelTypeInfo) + { + return !modelTypeInfo.IsAbstract && modelTypeInfo.GetConstructor(Type.EmptyTypes) != null; + } + private class ConfigureBuilder { public ConfigureBuilder(MethodInfo configure) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs index bef5912b9a..618765631f 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs @@ -1306,6 +1306,22 @@ namespace Microsoft.AspNetCore.Mvc.Core return string.Format(CultureInfo.CurrentCulture, GetString("MiddlewareFilter_ServiceResolutionFail"), p0, p1, p2, p3); } + /// + /// Unable to create an instance of type '{0}'. The type specified in {1} must not be abstract and must have a parameterless constructor. + /// + internal static string MiddlewareFilterConfigurationProvider_CreateConfigureDelegate_CannotCreateType + { + get { return GetString("MiddlewareFilterConfigurationProvider_CreateConfigureDelegate_CannotCreateType"); } + } + + /// + /// Unable to create an instance of type '{0}'. The type specified in {1} must not be abstract and must have a parameterless constructor. + /// + internal static string FormatMiddlewareFilterConfigurationProvider_CreateConfigureDelegate_CannotCreateType(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("MiddlewareFilterConfigurationProvider_CreateConfigureDelegate_CannotCreateType"), p0, p1); + } + /// /// An {0} cannot be created without a valid instance of {1}. /// diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx b/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx index 0575c33b57..8a35cabd50 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx +++ b/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx @@ -383,4 +383,8 @@ A duplicate entry for library reference {0} was found. Please check that all package references in all projects use the same casing for the same package references. {0} is the dependency name. + + Unable to create an instance of type '{0}'. The type specified in {1} must not be abstract and must have a parameterless constructor. + 0 is the type to configure. 1 is the name of the parameter, configurationType. + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MiddlewareFilterConfigurationProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MiddlewareFilterConfigurationProviderTest.cs index d5e2d77287..694606d8ce 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MiddlewareFilterConfigurationProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MiddlewareFilterConfigurationProviderTest.cs @@ -13,6 +13,22 @@ namespace Microsoft.AspNetCore.Mvc.Internal { public class MiddlewareFilterConfigurationProviderTest { + [Theory] + [InlineData(typeof(AbstractType))] + [InlineData(typeof(NoParameterlessConstructor))] + [InlineData(typeof(IDisposable))] + public void CreateConfigureDelegate_ThrowsIfTypeCannotBeInstantiated(Type configurationType) + { + // Arrange + var provider = new MiddlewareFilterConfigurationProvider(); + + // Act + var exception = Assert.Throws(() => provider.CreateConfigureDelegate(configurationType)); + + // Assert + Assert.Equal($"Unable to create an instance of type '{configurationType}'. The type specified in configurationType must not be abstract and must have a parameterless constructor.", exception.Message); + } + [Fact] public void ValidConfigure_DoesNotThrow() { @@ -174,5 +190,16 @@ namespace Microsoft.AspNetCore.Mvc.Internal } } + + private abstract class AbstractType + { + } + + private class NoParameterlessConstructor + { + public NoParameterlessConstructor(object a) + { + } + } } }