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.
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Core;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -19,7 +21,18 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1322,6 +1322,22 @@ namespace Microsoft.AspNetCore.Mvc.Core
|
|||
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)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</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>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
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
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
|
||||
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
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
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
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
|
@ -373,4 +373,7 @@
|
|||
<data name="AuthorizeFilter_AuthorizationPolicyCannotBeCreated" xml:space="preserve">
|
||||
<value>An {0} cannot be created without a valid instance of {1}.</value>
|
||||
</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>
|
||||
|
|
@ -12,6 +12,22 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
[Theory]
|
||||
[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(IList<int>))]
|
||||
[InlineData(typeof(int[]))]
|
||||
|
|
@ -45,5 +61,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
private class TestClass
|
||||
{
|
||||
}
|
||||
|
||||
private class DerviedFormCollection : FormCollection
|
||||
{
|
||||
public DerviedFormCollection() : base(fields: null, files: null) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue