In my interface I have a list of text boxes, something like this :
http://screencast.com/t/YjIxNjUyNmU
The number of textboxes is unknown as each of them is associated with a Template.
In my page, the goal is to associate a number to some of those templates.
Here is a sample HTML code :
<% // loop on the templates
foreach(ITemplate template in templates)
{
// get the content from the input dictionary
int val;
content.TryGetValue(template.Id, out val);
// convert it as a string
string value = ((val > 0) ? val.ToString() : string.Empty);
// compute the element name/id (for dictionary binding)
string id = ??????????
string name = ??????????????
%>
<label for="<%= name %>"><%= template.Name %></label>
<input type="text" id="<%= id %>" name="<%= name %>" value="<%= value %>" />
<br />
<% }
%>
What I expect, in my controller, is to get a IDictionary where the first int is the template ID , and the other is the count given by the user.
Here is what I want :
public ActionResult Save(int? id, Dictionary<int, int> countByTemplate)
I tried a lot of things but nothing worked. I tried to read the sources but it’s a maze, and I’m getting a headhache trying to get information about model binding.
Questions :
- is there a good ressource on how the modelbinding works ?
I’d like someting exhaustive, I’m tired of the 84093043 blogs that talk about a given specific example. - how can I build my HTML, using to get a IDictionary (or even a IDictionary in my controller’s action ?
Thanks a lot for your help
Ok… Thanks to Levi I was able to get on a solution.
Not the cleaner one, but it works.
The HTML should be written this way:
I had to add a hidden field to store the value.
I introduced a ‘fake’ counter just to loop over the dictionary the way ASP.Net MVC wants it.
As a result I got a dictionary filled with my values and ‘0’ when the textbox is empty.
Another problem appeared: the
ModelStatewas considered not valid because “a value is required”. I don’t want my values to be required, but looking at the modelbinder code, I did not found a way to tell the binder that a value is NOT required.So I tricked the
ModelStatein my controller, removing all error, like this:Well… I effectively got a solution, but the HTML is kind of ugly now, and counterintuitive (using an index to loop over a non-indexed collection ??).
And I need to trick each time I’ll use this kind of binding to have it all work properly.
So I will now open a new post to make dictionary binder something better.
Here it is: ASP.Net MVC 2 – better ModelBinding for Dictionary<int, int>
EDIT – There is a cleaner solution, thanks to Pavel Chuchuva.
In the controller code, use a nullable int as value for the dictionary.
A bit more code to add, but much cleaner.