Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC model binding an IList<> parameter

[I solved this myself, see my answer for cause]

I'm having trouble getting form values for a IList<> argument in a controller method set properly.

My controller class looks like this:

public class ShoppingBasketController : Controller {      public ActionResult Index() {         return View();     }      [AcceptVerbs(HttpVerbs.Post)]     public ActionResult Add(IList<ShoppingBasketItem> items) {         Session["basket"] = items; // for testing         return RedirectToAction("Index");     } } public class ShoppingBasketItem {      public int ItemID;      public int ItemQuantity; } 

The slightly trimmed form:

<% using (Html.BeginForm("Add", "ShoppingBasket")) { %>     <% int codeIndex = 0;     foreach (Product product in products) { %>         <%= Html.Hidden("items[" + codeIndex + "].ItemID", product.Id) %>         <%= Html.TextBox("items[" + codeIndex + "].ItemQuantity", "0", new { size = "2"}) %>         <% codeIndex++;     } } %> 

Which produces markup like:

<form action="/Basket/Add" method="post">     <input id="items[0]_ItemID" name="items[0].ItemID" type="hidden" value="1" />     <input id="items[0]_ItemQuantity" name="items[0].ItemQuantity" size="2" type="text" value="0" />      <input id="items[1]_ItemID" name="items[1].ItemID" type="hidden" value="2" />     <input id="items[1]_ItemQuantity" name="items[2].ItemQuantity" size="2" type="text" value="0" />      <input id="items[2]_ItemID" name="items[2].ItemID" type="hidden" value="3" />     <input id="items[2]_ItemQuantity" name="items[2].ItemQuantity" size="2" type="text" value="0" /> </form> 

I've checked the form values that get submitted and they are correct. The correct number of ShoppingBasketItems also get put into Session["basket"], however both the ItemID and ItemQuantity of each are zero. It appears to be correctly decoding the list of form values, but not picking up the properties themselves.

I'm using MVC RC2, and based on an article by Scott Hanselman I'm pretty sure my code is correct. Am I missing something?

like image 565
roryf Avatar asked Mar 17 '09 09:03

roryf


People also ask

What is model binding in ASP.NET MVC?

What Is Model Binding? ASP.NET MVC model binding allows mapping HTTP request data with a model. It is the procedure of creating . NET objects using the data sent by the browser in an HTTP request. Model binding is a well-designed bridge between the HTTP request and the C# action methods.

How do you bind data in Razor view?

Using the Razor syntax instead of plain HTML it is very easy to construct and bind your form elements to the corresponding data. In this case the label will show the value of the Display attribute in the User class and the values of the user will be filled in the textboxes.

Does MVC use data binding?

MVC doesn't use data bindings like old web api. You have to use model bindings in a MVC or MVVM approach.


1 Answers

Solution

After downloading the MVC source I still couldn't see why it wouldn't work, so I presumed it must be something to do with the type I was attempting to bind. Sure enough, the values being member variables, as opposed to properties, was the culprit. This is because the model binder uses reflection to set properties, which it wasn't finding through the call to TypeDescriptor.GetProperties(Type).

Updating the value class to this solved it (after hours of hitting head off wall I should add!!):

public class ShoppingBasketItem {     public int ItemID { get; set; }     public int ItemQuantity { get; set; } } 
like image 110
roryf Avatar answered Oct 11 '22 11:10

roryf