Reputation: 27811
In RoR, you can change the form context so that it properly builds the form element ids and names (e.g. simple_fields_for myModel do |innerModel|
, or similar). I'm wondering what's the correct way to do this w/MVC5. For example...
Models
class Model1 {
public Model2 M2 { get; set; }
}
class Model2 {
public List<Model3> M3s { get; set; }
}
class Model3 {
public string Name { get; set; }
}
Controller
class MyController {
public ActionResult Test(Model1 model) {
View(model);
}
}
View
@model Model1
@using (MvcForm form = Html.BeginForm()) {
Html.RenderPartial("_Model2", this.Model.M2);
}
If 3 Model3
instances are posted back, the model state should be similar to:
M2.M3s[0].Name=Name1
M2.M3s[1].Name=Name2
M2.M3s[2].Name=Name3
In this case, the view is using a partial to render Model2
, but the partial doesn't know that it's in the context of this.Model.M2
and therefore does not prefix the ids and names generated with Model2.
-- it simply starts them with Model3
. The solution would be to use a new form context (not literally meaning FormContext
), something like this:
@using (MvcForm form = Html.BeginForm()) {
using (form.For(m => m.M2)) {
Html.RenderPartial("_Model2", this.Model.M2);
}
}
Note that form.For
does not exist, but the intention is that it changes the current ModelMetadata
to have the appropriate context and prefix of M2
. Thus, anything rendered within that block would inherit that new context and the ids and names would be correctly generated.
Upvotes: 3
Views: 267
Reputation: 56439
You can actually specify the prefix when you call RenderPartial
, then the form values of your partial view fields will automatically receive that prefix:
Html.RenderPartial("_Model2", this.Model.M2, new ViewDataDictionary
{
TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "M2" }
})
Upvotes: 2