How do you handle the output of a dynamically generated form in ASP.NET MVC?

Suppose you create a form using ASP.NET MVC with a dynamic number of form elements.

For example, you need to check the box for each product, and the number of products changes day by day.

How would you process the data of this form sent back to the controller? You cannot configure the parameters in the action method because you do not know how many form values โ€‹โ€‹will be returned.

+4
source share
4 answers

Just give each checkbox a unique name:

<input class="approveCheck" id="<%= "approveCheck" + recordId %>" name="<%= "approveCheck" + recordId %>" type="checkbox" /> 

Then parse the list of form values โ€‹โ€‹in Action, after submitting:

 foreach (var key in Request.Form.Keys) { string keyString = key.ToString(); if (keyString.StartsWith("approveCheck", StringComparison.OrdinalIgnoreCase)) { string recNum = keyString.Substring(12, keyString.Length - 12); string approvedKey = Request.Form["approveCheck" + recNum]; bool approved = !String.IsNullOrEmpty(approvedKey); // ... 

You do not need to pass form values โ€‹โ€‹as arguments; you can just get them from Request.Form.

Another option: write a mediator to change the list to a custom type to submit the form.

+5
source

Craig's answer is safer. There are quirks for placing multiple form elements with the same name. I would add that it would be wise to wrap the logic that makes the โ€œcollectionโ€ of controls similar to WebForms. Web Forms adds a container control name and adds an index. For example, in Repeater, the form elements inside would be called (something like) RepeaterName_Element1, RepeaterName_Element2. When you go to get items, you should use FindControl or something like that.

+2
source

Depending on the binders you use, this should work:

 <%var i = 0; foreach (var product (IList<ProductSelection>)ViewData["products"]) {%> <%=Html.Hidden(string.Format("products[{0}].Id", i), product.Id)%> <%=Html.Checkbox(string.Format("products[{0}].Selected", i))%> <%=product.Name%><br/> <%}%> 

..., which will cause HTML to be something like this (note the array notation for names):

 <input name="products[0].Id" type="hidden" value="123"> <input name="products[0].Selected" type="checkbox"> Widget <input name="products[1].Id" type="hidden" value="987"> <input name="products[1].Selected" type="checkbox"> Gadget 

... and the controller method that processes the message:

 public ActionResult SelectProducts(IList<ProductSelection> products) { ... } 

When bound, the products parameter will contain two instances of ProductSelection.

One caveat is that I did not use the new default binding for complex objects. Rather, I use either NameValueDeserializer or CastleBind, as from MvcContrib. They both behave like that. I assume beta binding will work the same.

+2
source

Depending on your data, you can either output a "CheckboxList" (which is no longer possible in newer versions), use the string[] parameter, or you can configure several forms and just change the action.

0
source

All Articles