views:

153

answers:

3

I have a form which contains a series of fields like:

<input type="text" name="User[123]" value="Alice" />
<input type="text" name="User[456]" value="Bob" />
...

Where the index of the User array (123 and 456) are ID's associated with the value. I'm trying to update these values in the controller. My thinking is that a Dictionary that maps ID to name would work, but creating the action like:

public void Save(Dictionary<string, string> user) {
    // ...
}

results in the user parameter being null.

So, is passing a Dictionary possible? or, is there another method to achieve this?

+6  A: 

It's possible for lists, I'm sure it carries over for dictionaries as well. Read through Model Binding to a List by Phil Haack for some understanding on how list binding works.

You should be able to do this:

<input type="hidden" name="User.Index" value="123" />
<input type="text" name="User[123]" value="Alice" />

<input type="hidden" name="User.Index" value="456" />
<input type="text" name="User[456]" value="Bob" />
womp
That post is obsolete. Format for binding to lists changed, you don't need to specify indexes.
queen3
The post is not obsolete. It was updated with information relevant to MVC 2 and to take into account that ".index" is optional.
Levi
@Levi Are you sure? The code sample above doesn't work for me. I get null as user parameter in Save method. I have MVC 2 RTM and VS 2008.
Pavel Chuchuva
Remember - when you model bind to a dictionary, you're actually binding to an ICollection<KeyValuePair<,>>. So you need User[x].Key and User[x].Value (to reconstitute the KeyValuePair object). See http://marcomagdy.com/2009/09/03/asp-net-mvc-model-binding-form-inputs-to-action-parameters/ for an example.
Levi
+3  A: 

See http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx for the syntax necessary to bind to a dictionary. Note in particular the example of binding MSFT + AAPL company tickers around halfway down that post.

Levi
A: 

For ASP.NET MVC 2 use this:

<input type="hidden" name="User[0].Key" value="123" />
<input type="text" name="User[0].Value" value="Alice" />

<input type="hidden" name="User[1].Key" value="456" />
<input type="text" name="User[1].Value" value="Bob" />

You need an extra hidden field User[i].Key. i is zero-based index. It should be uninterrupted.

when you model bind to a dictionary, you're actually binding to an ICollection<KeyValuePair<,>>. So you need User[x].Key and User[x].Value (to reconstitute the KeyValuePair object)

References

Pavel Chuchuva