Reputation: 7269
Hello I have a model object defined in an MVC 3 project that has a Dictionary property as follows:
MyObj.ObjDictionary<string,string>
I have two controller methods, one which handles returning the view and another that handles the POSTed form from the view
public ActionResult Scanner(string val_1, string val_2, string val_3)
{
//Fetch sessionObj from Model
MyObj sessionObj = getSessionObj(val_1, val_2, val_3);
//At this point model.ObjDictionary<string,string> contains data
return View(sessionObj);
}
[HttpParamAction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Scanner(MyObj model)
{
//At this point model.ObjDictionary<string,string> is null
//i.e. binding is not being properly achieved
//Validate POSTed data
}
In the View, I iterate through each key-value pair (kvp). It has to be done this way since the property is dynamic and I have no way of knowing how many dictionary values there will be.
@using (Html.BeginForm("Action", "Home"))
{
@foreach (var kvp in Model.ObjDictionary)
{
<span>@Html.Label("Scan " + @kvp.Key)</span>
<span>@Html.TextBox(kvp.Key, "", new { @style = "font-size:Medium;width:400px;" })</span>
}
<input type="submit" name="Cancel" value="Cancel" />
<input type="submit" id="Scanner" name="Scanner" value="Scanner" />
}
The goal is to provide a way for users to input data and have that data bound to the values of the specific key. My problem is that the Model.ObjDictionary is null when it gets POSTed. I'm not sure what I'm doing wrong, I read over this article, but this assumes pre-existing values in a dictionary. Is there a way the ModelBinder can bind the data, entered by a user, to a dictionary value mapped to a specific key?
Upvotes: 2
Views: 2840
Reputation: 16636
For dictionaries, each entry should have one field for the key and one field for the value.
@using (Html.BeginForm("Action", "Home"))
{
var index = 0;
@foreach (var kvp in Model.ObjDictionary)
{
<span>@Html.Hidden("ObjDictionary[" + index + "].Key", kvp.Key)
<span>@Html.Label("Scan " + @kvp.Key)</span>
<span>@Html.TextBox("ObjDictionary[" + index + "].Value", kvp.Value, new { @style = "font-size:Medium;width:400px;" })</span>
index++;
}
<input type="submit" name="Cancel" value="Cancel" />
<input type="submit" id="Scanner" name="Scanner" value="Scanner" />
}
By the way, I have encapsulated this functionality in an HTML helper class. You can find it and a working demonstration here: https://github.com/ErikSchierboom/aspnetmvcdictionaryserialization
Upvotes: 0
Reputation: 4282
The article you referenced answers your question, you simply need to provide the correct names for your controls, try:
@using (Html.BeginForm("Action", "Home")) {
var i = 0;
foreach (var kvp in Model.ObjDictionary)
{
@Html.Hidden("ObjDictionary[" + i + "].Key", kvp.Key)@kvp.Key
<span>@Html.TextBox("ObjDictionary[" + i + "].Value", kvp.Value, new { @style = "font-size:Medium;width:400px;" })</span>
i++;
<br />
}
<input type="submit" value="Submit" />
}
Upvotes: 3