Ok, this is weird. I cannot use BindAttribute
's Include
and Exculude
properties with complex type nested objects on ASP.NET MVC.
Here is what I did:
This is my model:
public class FooViewModel {
public Enquiry Enquiry { get; set; }
}
public class Enquiry {
public int EnquiryId { get; set; }
public string Latitude { get; set; }
}
HTTP Post action:
[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(
[Bind(Include = "Enquiry.EnquiryId")]
FooViewModel foo) {
return View(foo);
}
View:
@using (Html.BeginForm()) {
@Html.TextBoxFor(m => m.Enquiry.EnquiryId)
@Html.TextBoxFor(m => m.Enquiry.Latitude)
<input type="submit" value="push" />
}
Does not work at all. Can I only make this work if I define the BindAttribute
for Enquiry
class as it is stated here:
How do I use the [Bind(Include="")] attribute on complex nested objects?
Yes, you can make it work like that:
and your action:
This will include only the
EnquiryId
in the binding and leave theLatitude
null.This being said, using the Bind attribute is not something that I would recommend you. My recommendation is to use view models. Inside those view models you include only the properties that make sense for this particular view.
So simply readapt your view models:
There you go. No longer need to worry about binding.
IMHO there is a better way to do this.
Essentially if you have multiple models in the view model the post controller's signature would contain the same models, as opposed to the view model.
I.E.
And the post action in the controller would look like this.
All while the view still looks like this
Keep in mind, this form will still post Latitude back (the way you had it set up), however since it is not included in the Bind Include string for Enquiry on the post action, the action will not accept the new value in the resultant Enquiry. I'd suggest making latitude either disabled or not a form element to prevent additional posting data.
In any other scenario you can use bind just fine, but for some reason it dislikes the dot notation for complex models.
As a side note, I wouldn't put the bind attribute on the class directly as it can cause other issues like code replication, and doesn't account for certain scenarios where you may want to have a different binding.
(I modified the variable names for some clarity. I am also aware your question is rather dated, however in searching for the answer myself this is the first SO I stumbled upon before trying my own solutions and coming to the one I posted. I hope it can help out other people seeking a solution to the same issue.)