I have a problem similar to the hypothetical below. I have added partial views to another view multiple times but I'm not sure how to get them to bind properly to the view model etc. Also, the validation seems to trigger for every single fooName if a single fooName is wrong. I've added the index to the viewbag as you can see but I'm not really sure how to use it yet.
Note:Using MVC5.2
View Models
public class Thing
{
public String thingName { get; set; }
public List<Foo> Foos { get; set; }
}
public class Foo
{
public String fooName { get; set; }
}
Foo View
@model Project.Models.Foo
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-12">
@Html.LabelFor(model => model.fooName, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.fooName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.fooName, "", new { @class = "text-danger" })
</div>
</div>
</div>
Thing View
@model Project.Models.Thing
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-12">
@Html.LabelFor(model => model.thingName, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.thingName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.thingName, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="add-foo">
@* at some point add more foos with ajax, for now k.i.s.s. *@
@Html.Partial("/Views/Foo/Create.cshtml", new ViewDataDictionary { { "id", 1 } })
@Html.Partial("/Views/Foo/Create.cshtml", new ViewDataDictionary { { "id", 2 } })
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
}
The problem here is that the
Foo
partial is rendering without context of the larger model at play. As a result you're getting a bunch of inputs with all the same names and ids, i.e.:That's why the validation is triggering on all of them, because they are all the same. In order to have the partial behave correctly, you would need to pass some context into it. For example, if you were iterating over existing instances of something you could do:
Based on the
Model.Foos[i]
bit, Razor would then generate proper input names likeFoos[0].fooName
,Foos[1].fooName
, etc.Or, you can override the
HtmlFieldPrefix
:Since you're planning on being able to add additional ones dynamically via JavaScript, your best bet though is to rely on something like Knockout or Angular to render the fields for you based on a JavaScript array. Then, when you add new
Foo
instances to that array, the library will automatically add additional fields to the page with an indexed name attribute.