I have a view model like:
public class OrganisationViewModel
{
public string OrganisationName { get; set; }
public List<BranchViewModel> Branches { get; set; }
// more properties...
}
public class BranchViewModel
{
public string BranchName { get; set; }
// more properties...
}
This is how the Organisation page looks like:
What I want to achieve is to allow user to update a single BranchViewModel
, so I have created a Modal for each Branch and when user click on the Edit branch link, the modal will open:
@for (int i = 0; i < Model.BranchViewModels.Count(); i++)
{
var branchModalId = OrganisationHelper.GetBranchModalId(Model.BranchViewModels[i].BranchId);
<div class="modal fade" id="@branchModalId" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<form action="/organisation/updateBranch" method="post" role="form">
<div class="modal-body">
@Html.AntiForgeryToken()
<div class="form">
<div class="form-group">
@Html.LabelFor(m => Model.BranchViewModels[i].BranchName, htmlAttributes: new { @class = "", @maxlength = GlobalConstants.MaxLengthForLongName })
@Html.TextBoxFor(m => Model.BranchViewModels[i].BranchName, new { @class = "form-control input-text" })
@Html.ValidationMessageFor(m => Model.BranchViewModels[i].BranchName, "", new { @class = "text-danger" })
</div>
@*more properties...*@
</div>
</div>
<div class="modal-footer">
<input type="button" value="Cancel" class="btn btn-secondary-grey" data-dismiss="modal" />
<input type="submit" class="btn btn-primary-action" value="Save" />
</div>
</form>
</div>
</div>
</div>
}
Now the problem is, since branches belong to an array the inputs on the page are generated as an array, so something like this:
<input class="form-control input-text" data-val="true" id="BranchViewModels_0__BranchName" name="BranchViewModels[0].BranchName" readonly="readonly" type="text" value="35671900246">
So when I submit the changes to the branch, the values are passed to the controller as List
, so this controller will accept a List of one Branch:
public ActionResult UpdateBranch(List<BranchViewModel> branchViewModel)
{
}
What I want to achieve is to be able to pass the single branch to the controller, so I want the signature of the controller to be like:
public ActionResult UpdateBranch(BranchViewModel branchViewModel)
{
}
But I need the branch to be rendered as an array in the HTML, otherwise I will get duplicated input Ids… what is the best way to achieve this?
2
Answers
Can you try instead of using the static
@HTML.LabelFor
and@HTML.TextBoxFor
, you could write the html manually with<input>
tags and specify the name of the input field. This way, it won’t have an index.Full modal code;
ASP.NET MVC serialization works on html element names. Indexers will have html element names with _i__ (where i is index of branch in that collection) when you create them via for loop.
So, instead of using indexers (accessing Model.BranchViewModels[i] via for loop), you can try using foreach.