-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[Part1 of #4895] Modified FormCollectionModelBinderProvider to throw when binding for... #5368
Conversation
|
||
if (typeof(FormCollection).GetTypeInfo().IsAssignableFrom(modelType)) | ||
{ | ||
throw new InvalidOperationException( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is different than what the bug suggests at the solution. #4895 (comment)
This special cases FormCollection
- the suggestion was to check for a no-arg constructor in the Complex type provider and instead of throwing an exception, just let it pass through, the system will throw if a model binder can't be created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dougbu and I discussed about this and divided this into 2 parts:
- In Part1 (this PR), we would explicitly check for
FormCollection
inFormCollectionModelBinderProvider
and throw so that users do not mistake it to be a type that we support binding to. - In Part2 we would like to handle the
no arg
constructor scenario inComplexTypeModelBinderProvider
Question regarding:
the suggestion was to check for a no-arg constructor in the Complex type provider and instead of throwing an exception, just let it pass through, the system will throw if a model binder can't be created.
Following is the current(1.0.0) behavior of the system where it gives good enough details for a user to understand whats wrong, so wondering what you meant:
An unhandled exception has occurred while executing the request
System.ArgumentException: Type 'MvcSandbox.Controllers.Customer' does not have a default constructor
Parameter name: type
at System.Linq.Expressions.Expression.New(Type type)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.CreateModel(ModelBindingContext bindingContext) in C:\github\mvc\src\Microsoft.AspNetCore.Mvc.Core\ModelBinding\Binders\ComplexTypeModelBinder.cs:line 325
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.<BindModelCoreAsync>d__4.MoveNext() in C:\github\mvc\src\Microsoft.AspNetCore.Mvc.Core\ModelBinding\Binders\ComplexTypeModelBinder.cs:line 60
--- End of stack trace from previous location where exception was thrown ---
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ignore my clarification question...I understood what you meant.
@@ -10,8 +10,32 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders | |||
{ | |||
public class FormCollectionModelBinderProviderTest | |||
{ | |||
class DerviedFormCollection : FormCollection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private class
and stick this at the bottom of the file.
I don't think it's the end of the world, but ideally MBPs don't throw exceptions. In this case it seems ok because we 'own' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⌚️ for a couple of small changes
typeof(FormCollectionModelBinder).FullName, | ||
modelType.FullName, | ||
typeof(IFormCollection).FullName), | ||
exception.Message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be more readable if this used string
interpolation and the Assert.Throws<TEx>
overload that takes the expected message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the Assert.Throws overload that takes the expected message.
I am unable to find this overload
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I got confused between default and ExceptionAssert
overloads. Don't change this further.
🆙 📅 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor but the first "to" and trailing "instead" make this less readable. "cannot bind a model ..." and "change the model type to ..." don't need the extra words.
…FormCollection model type. [Fixes #4895] No parameterless Constructor defined
4f38590
to
d09e921
Compare
…FormCollection model type.
Part 1 of [Fixes #4895] No parameterless Constructor defined
I will send the fix for ComplexTypeModelBinderProvider in a separate PR
@dougbu @rynowak