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

Creating correct model state keys when body model binding for missing properties or body. Also adds integration tests #2396

Closed
wants to merge 0 commits into from

Conversation

harshgMSFT
Copy link
Contributor

The model state keys for body bound models which are bound at property will use the entire model name with this change for example
Consider

        public class Person
        {
            [FromBody]
            public Address Address { get; set; }
        }

        public class Address
        {
            [Required]
            public string Street { get; set; }

            public int Zip { get; set; }
        }

Request body { "Zip" : 12345 }
In this case the error key would be "prefix.Address.Street" (assuming there is a prefix because of additional metadata/positioning for/of the Person model).

public class Person
{
       [Required]
       public string Name { get; set; }
}

public void Action([FromBody]Person p)
{
}

Request body { }
In this case the prefix gets ignored and the error key is Name.
Please note this is so that we are compatible with MVC 5.0

public class Person
{
       [Required]
       public string Name { get; set; }
}

public void Action([FromBody][ModelBinder(Name = "prefix")] Person p)
{
}

public void Action2([FromBody][Bind(Name = "prefix")] Person p)
{
}

Request body { }
In both these cases (Action and Action2) the prefix gets ignored and the error key is Name.
This is a slight improvement from mvc, as in MVC the action parameter would be null.

The followup for this would be to fix #2416 -
This PR ignores the validation assuming that #2416 will address the issues and update the test.

NOTE: previous versions of mvc did not have property binding and hence there is no precedence in this case. For MVC and Web API it was possible to body bind an action parameter which used an empty prefix instead of a parameter name for adding errors to model state (In case of MVC if a custom prefix was provided, it failed binding from body i.e the parameter was null).

@ghost ghost added the cla-already-signed label Apr 17, 2015
@@ -13,5 +13,8 @@
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure why this shows up.

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 fine. just means it is a test project. check it in separately, together w/ the rest of this PR, or whatever...

Copy link
Member

Choose a reason for hiding this comment

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

In general just let VS do what it's going to do.

@dougbu
Copy link
Member

dougbu commented Apr 17, 2015

@harshgMSFT it isn't clear what the expected behaviour is in any of the cases you've outlined or why the current behaviour is incorrect. please describe the exact Asp.Net 4 and MVC 5 behaviours for these cases.

separately what reported issues (if any) will this PR fix?


namespace Microsoft.AspNet.Mvc.Core
{
public class TestMvcOptions : IOptions<MvcOptions>
Copy link
Member

Choose a reason for hiding this comment

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

name of class and containing file must match

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix.

@harshgMSFT
Copy link
Contributor Author

@dougbu I have updated the comment to provide a better description. And no there is no issue for this one.

return modelBindingResult.Model;
}

return null;
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 a good refactor. I had scoped out something similar thinking about building these tests.

@harshgMSFT harshgMSFT force-pushed the BodyValidationFix branch 2 times, most recently from 8a10233 to 49b2eb9 Compare April 21, 2015 16:06
@harshgMSFT harshgMSFT changed the title Fixing inconsistencies in the body model binding behavior in case of a missing property, or missing body. Creating correct model state keys when body model binding for missing properties or body. Also adds integration tests Apr 21, 2015
@harshgMSFT
Copy link
Contributor Author

@dougbu @rynowak updated with the behaviors agreed on.

@@ -51,8 +51,13 @@ public BodyModelBinder()
{
var model = await formatter.ReadAsync(formatterContext);

// key is empty to ensure that the model name is not used as a prefix for validation.
return new ModelBindingResult(model, key: string.Empty, isModelSet: true);
var isTopLevelObject = bindingContext.ModelMetadata.ContainerType == null;
Copy link
Member

Choose a reason for hiding this comment

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

Didn't we conclude in another discussion that this kind of logic is incorrect, and we can only really know this by adding it back to the context?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, however that is a corner scenario and we should address this when we address that issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rynowak
Copy link
Member

rynowak commented Apr 21, 2015

:shipit:

@@ -63,6 +63,41 @@ public class DefaultControllerActionArgumentBinder : IControllerActionArgumentBi
return actionArguments;
}

public async Task<ModelBindingResult> BindModelAsync(
Copy link
Member

Choose a reason for hiding this comment

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

this class has a <summary/> but no member-level doc comments. prefer if you add comments for new public method but at least open a "task" issue to do the necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will add doc comments for the public api surface for this class in a separate pr ( not holding this one for furhter review (as you have already signed off)). Not opening individual issues for adding doc comments, there are tons of places which needs fixing and this could be tracked by a singular issue.

@dougbu
Copy link
Member

dougbu commented Apr 22, 2015

:shipit: with the perfect doc comment addition 😸

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.

3 participants