Saeid
Saeid

Reputation: 13592

Send a Complex Object as a Parameter to Post Action in ASP.NET MVC3

I try to send a parameter with submit button to post action so there is my sample:

@using(Html.BeginForm(actionName: "Search", controllerName: "MyController", routeValues: new { rv = "102" })) {

   ...
  <input type="submit" value="Search" />
}

And this is My Search Action:

[HttpPost]
public virtual ActionResult Search(string rv, FormCollection collection) {

 ...
}

So Every thing is fine until now,

Then I try to Send a complex object like a Dictionary<string, string>

So you can just replace string type of rv parameter with Dictionary<string, string> and send a dictionary, but in this case the rv value always returned a dictionary with 0 count? where is the problem? How can I send a dictionary to post action?

Update

I Also try this one but not worked yet (Mean rv steel is a dictionary with 0 count):

@using(Html.BeginForm(actionName: "Search", controllerName: "MyController", routeValues: new { rv = Model.MyDictionary }, method: FormMethod.Post, htmlAttributes: new { @class = "FilterForm" })) {

 ...
}

[HttpPost]
public virtual ActionResult Search(Dictionary<string, string> rv, FormCollection collection) {

 ...
}

Upvotes: 3

Views: 4268

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039050

You cannot send complex objects. Please read the following article to the understand the expected wire format that the default model binder expects if you want to be able to deserialize the object to a collection or a dictionary.

So after reading ScottHa's article and understanding the expected wire format for dictionaries you could roll a custom extension method that will convert your dictionary to a RouteValueDictionary following the conventions:

public static class DictionaryExtensions
{
    public static RouteValueDictionary ToRouteValues(this IDictionary<string, string> dict)
    {
        var values = new RouteValueDictionary();
        int i = 0;
        foreach (var item in dict)
        {
            values[string.Format("[{0}].Key", i)] = item.Key;
            values[string.Format("[{0}].Value", i)] = item.Value;
            i++;
        }
        return values;
    }
}

and then in your view you could use this extension method:

@using(Html.BeginForm(
    actionName: "Search", 
    controllerName: "MyController", 
    routeValues: Model.MyDictionary.ToRouteValues(), 
    method: FormMethod.Post, 
    htmlAttributes: new RouteValueDictionary(new { @class = "FilterForm" }))
) 
{
    ...
}

Obviously here I assume that Model.MyDictionary is an IDictionary<string, string> property.

Upvotes: 4

Related Questions