Help with ModelBinding complex objects in .net
I have a custom modelbinder built to handle my accountRequest class. This class consists of some boolean values and a UserViewModel.
The UserViewModel is made up of strings such as Firstname, Last Name, Address.
Originally I was just passing the UserViewModel as the action parameter but I now I need to package UserViewModel inside of accountRequest.
however, now my modelbinder will not map the strings in the httpContext.Request开发者_StackOverflow社区 to my UserViewModel inside of AccountRequest. All of the booleans map just fine.
Is there an easy way to get his data to map to the UserViewModel properties other than hardcoding it?
I have attempted this but I dont like it. (simplified)
Dim accountRequest As New AccountRequest
Dim user As New UserViewModel
If Not String.IsNullOrEmpty(controllerContext.HttpContext.Request("Firstname")) Then
user.FirstName = controllerContext.HttpContext.Request("Firstname")
End If
accountRequest.CurrentUser = user
Return accountRequest
Obviously any help is greatly appreciated. Thanks in advance!
Sorry - just realised that your code was VB and I've answered in C#
This could be because the model binder is now looking modelname.property
instead of just property
in the ValueProviders and, previously, because it was a direct action method parameter, it would have just been looking for property
.
Now that the model type is a member of another, its property name will be used as a prefix and I don't believe you can remove that requirement (could try Bind(Prefix="")
on the parameter, but I don't think that'll work).
This is assuming you aren't custom-binding every property and that the DefaultModelBinder
is doing some of these properties for you.
You should be able to make it work, without changing code, by altering your query string to be ?modelname.property=[value]
. If you're using a Form, then you should consider using the Html.EditorFor
extension method - as it takes care of model naming (so long as your ViewModel member names and input model names are consistent). But as an example from the query string:
public class MyObject{
public string StringValue { get; set; }
}
public class MyObjectOuter{
public MyObject Nested { get; set; }
}
public ActionResult Index(MyObjectOuter obj);
The obj.Nested.StringProperty value can be filled with: /Index?Nested.StringValue=hello%20world
because the obj
prefix is implicit anyway.
If you don't like this, you have a couple of options:
1) Change the signature of the method to take two parameters:
public ActionResult Index(MyObjectOuter outer, MyObject nested)
And then in the body you immediately copy nested
to the obj.Nested
property. This is a little bit hacky - but it'll work.
2) Manually force the bind of your class' properties to use non-prefixed values from the ValueProviders
(but then you're limiting your model type to only work with certain types of request - which isn't exactly flexible).
3) Or, like I said earlier, if these properties are being bound from an Http Form, use Html.EditorFor
to generate the markup - it automatically generates inputs with the correct names, so long as they don't change from input->output.
精彩评论