I have a class called CategoryModel
, one of the properties of which is a list of objects of the same type. So CategoryModel.Categories
is of type List<CategoryModel>
.
On the category index page, I display an editor for each category so that the user can change any of the category names without having to go to a dedicated page to do so. Like so:
<ul id="categories>
@Html.EditorFor(model => model.Categories)
</ul>
And the editor template for CategoryModel
looks like this:
<li class="folder">
@using (Html.BeginForm("Edit", "Category", new { id = Model.Key }, FormMethod.Post, new { @class = "ajaxoff"})) {
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.Key)
@Html.HiddenFor(model => model.ParentKey)
@Html.HiddenFor(model => model.Sequence)
@Html.HiddenFor(model => model.IncludeDeleted)
@Html.TextBoxFor(model => model.Name, null, new { @class = "catName" })
@Html.ValidationMessageFor(model => model.Name)
<input type="submit" value="Save" class="icon save" />
}
</li>
The problem I have is that submitting the form does not bind correctly to the Edit
action of the CategoryController
:
[HttpPost]
public ActionResult Edit(CategoryModel category)
{
// At this point all properties in category are null
}
If I check the names on the hidden fields and textboxes, they are labelled based on their position in the current category (e.g. Categories[0].Name
). If I create a dedicated edit view, however, they are simply named according to the field name (e.g. Name
).
I have tried changing the controller to accept a list of Categories:
[HttpPost]
public ActionResult Edit(List<CategoryModel> categories)
{
var category = categories.First();
}
This works if I submit the very first category, but none of the others (in those cases Categories
is null).
I have also tried changing how I display my EditorFor, by doing this:
<ul id="categories>
@foreach (var cat in Model.Categories)
{
@Html.EditorFor(model => cat);
}
</ul>
Which changes the field names to be the same for each category (e.g. all category names are called cat.Name
), which I believe is a step in the right direction.
So how do I bind correctly to my controller? I realise that I could submit the whole parent category and then save each subcategory, but this seems like a very inefficient way to submit a single change.
I discovered how to do this. There is an overload for Html.EditorFor
that allows you to specify the htmlFieldName
property (the third parameter in the example below):
@foreach (var cat in Model.Categories)
{
@Html.EditorFor(model => cat, null, "");
}
This renders all of the field names without any prefix and allows me to submit any single category successfully.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With