Modified FormCollectionModelBinderProvider to throw when binding for FormCollection model type.
[Fixes #4895] No parameterless Constructor defined
This commit is contained in:
parent
e987e2107f
commit
e7fe635dab
|
|
@ -2,7 +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.Reflection;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Core;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||||
{
|
{
|
||||||
|
|
@ -19,7 +21,18 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||||
throw new ArgumentNullException(nameof(context));
|
throw new ArgumentNullException(nameof(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Metadata.ModelType == typeof(IFormCollection))
|
var modelType = context.Metadata.ModelType;
|
||||||
|
|
||||||
|
if (typeof(FormCollection).GetTypeInfo().IsAssignableFrom(modelType))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
Resources.FormatFormCollectionModelBinder_CannotBindToFormCollection(
|
||||||
|
typeof(FormCollectionModelBinder).FullName,
|
||||||
|
modelType.FullName,
|
||||||
|
typeof(IFormCollection).FullName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modelType == typeof(IFormCollection))
|
||||||
{
|
{
|
||||||
return new FormCollectionModelBinder();
|
return new FormCollectionModelBinder();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1322,6 +1322,22 @@ namespace Microsoft.AspNetCore.Mvc.Core
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("AuthorizeFilter_AuthorizationPolicyCannotBeCreated"), p0, p1);
|
return string.Format(CultureInfo.CurrentCulture, GetString("AuthorizeFilter_AuthorizationPolicyCannotBeCreated"), p0, p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The '{0}' cannot bind to a model of type '{1}'. Change the model type to '{2}' instead.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormCollectionModelBinder_CannotBindToFormCollection
|
||||||
|
{
|
||||||
|
get { return GetString("FormCollectionModelBinder_CannotBindToFormCollection"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The '{0}' cannot bind to a model of type '{1}'. Change the model type to '{2}' instead.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatFormCollectionModelBinder_CannotBindToFormCollection(object p0, object p1, object p2)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("FormCollectionModelBinder_CannotBindToFormCollection"), p0, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetString(string name, params string[] formatterNames)
|
private static string GetString(string name, params string[] formatterNames)
|
||||||
{
|
{
|
||||||
var value = _resourceManager.GetString(name);
|
var value = _resourceManager.GetString(name);
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
|
|
||||||
Version 2.0
|
Version 2.0
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
The primary goals of this format is to allow a simple XML format
|
||||||
that is mostly human readable. The generation and parsing of the
|
that is mostly human readable. The generation and parsing of the
|
||||||
various data types are done through the TypeConverter classes
|
various data types are done through the TypeConverter classes
|
||||||
associated with the data types.
|
associated with the data types.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
... ado.net/XML headers & schema ...
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
<resheader name="version">2.0</resheader>
|
<resheader name="version">2.0</resheader>
|
||||||
|
|
@ -26,36 +26,36 @@
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
<comment>This is a comment</comment>
|
<comment>This is a comment</comment>
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
There are any number of "resheader" rows that contain simple
|
||||||
name/value pairs.
|
name/value pairs.
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
Each data row contains a name, and value. The row also contains a
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
text/value conversion through the TypeConverter architecture.
|
text/value conversion through the TypeConverter architecture.
|
||||||
Classes that don't support this are serialized and stored with the
|
Classes that don't support this are serialized and stored with the
|
||||||
mimetype set.
|
mimetype set.
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
The mimetype is used for serialized objects, and tells the
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
read any of the formats listed below.
|
read any of the formats listed below.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
value : The object must be serialized into a byte array
|
value : The object must be serialized into a byte array
|
||||||
: using a System.ComponentModel.TypeConverter
|
: using a System.ComponentModel.TypeConverter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
-->
|
-->
|
||||||
|
|
@ -373,4 +373,7 @@
|
||||||
<data name="AuthorizeFilter_AuthorizationPolicyCannotBeCreated" xml:space="preserve">
|
<data name="AuthorizeFilter_AuthorizationPolicyCannotBeCreated" xml:space="preserve">
|
||||||
<value>An {0} cannot be created without a valid instance of {1}.</value>
|
<value>An {0} cannot be created without a valid instance of {1}.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="FormCollectionModelBinder_CannotBindToFormCollection" xml:space="preserve">
|
||||||
|
<value>The '{0}' cannot bind to a model of type '{1}'. Change the model type to '{2}' instead.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -12,6 +12,22 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(typeof(FormCollection))]
|
[InlineData(typeof(FormCollection))]
|
||||||
|
[InlineData(typeof(DerviedFormCollection))]
|
||||||
|
public void Create_ThrowsException_ForFormCollectionModelType(Type modelType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var provider = new FormCollectionModelBinderProvider();
|
||||||
|
var context = new TestModelBinderProviderContext(modelType);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<InvalidOperationException>(() => provider.GetBinder(context));
|
||||||
|
|
||||||
|
Assert.Equal(
|
||||||
|
$"The '{typeof(FormCollectionModelBinder).FullName}' cannot bind to a model of type '{modelType.FullName}'. Change the model type to '{typeof(IFormCollection).FullName}' instead.",
|
||||||
|
exception.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
[InlineData(typeof(TestClass))]
|
[InlineData(typeof(TestClass))]
|
||||||
[InlineData(typeof(IList<int>))]
|
[InlineData(typeof(IList<int>))]
|
||||||
[InlineData(typeof(int[]))]
|
[InlineData(typeof(int[]))]
|
||||||
|
|
@ -45,5 +61,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||||
private class TestClass
|
private class TestClass
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DerviedFormCollection : FormCollection
|
||||||
|
{
|
||||||
|
public DerviedFormCollection() : base(fields: null, files: null) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue