Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

[Part1 of #4895] Modified FormCollectionModelBinderProvider to throw when binding for... #5368

Merged
merged 2 commits into from
Oct 8, 2016

Conversation

kichalla
Copy link
Member

@kichalla kichalla commented Oct 5, 2016

…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


if (typeof(FormCollection).GetTypeInfo().IsAssignableFrom(modelType))
{
throw new InvalidOperationException(
Copy link
Member

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.

Copy link
Member Author

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 in FormCollectionModelBinderProvider 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 in ComplexTypeModelBinderProvider

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 ---

Copy link
Member Author

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
Copy link
Member

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.

@rynowak
Copy link
Member

rynowak commented Oct 5, 2016

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' IFormCollection/FormCollection. Order matters with MPBs and so throwing an exception means that other providers can't handle it.

Copy link
Member

@dougbu dougbu left a 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);
Copy link
Member

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.

Copy link
Member Author

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

Copy link
Member

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.

@kichalla
Copy link
Member Author

kichalla commented Oct 6, 2016

🆙 📅

Copy link
Member

@dougbu dougbu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@@ -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>
Copy link
Member

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.

@kichalla kichalla force-pushed the kichalla/formfilecollection-binding branch from 4f38590 to d09e921 Compare October 8, 2016 00:01
@kichalla kichalla merged commit d09e921 into dev Oct 8, 2016
@kichalla kichalla deleted the kichalla/formfilecollection-binding branch January 30, 2017 19:56
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants