Okay, I’m not trying to do anything super complex, I have searched, and searched, and roamed every blog and forum I can find. I am about to tear my hair out because no one just outright shows it working.
I want to use an IDictionary in my Model. Nevermind the reason why, that’s irrelevant. I just want to do something very simple, and understand what is going on.
Can someone please help me figure out the HTML I should be putting in the View to make this work right? Please? I have tried Html.TextBoxFor and it comes back null on the postback. I have tried manually using the index of the dictionary item, and it comes back null. I am really getting frustrated, and all I keep seeing is redirection to blogs that don’t answer the question.
Controller
public ActionResult DictionaryView()
{
var model = new Dictionary<string, int>
{
{ "First", 0 },
{ "Second", 0 },
{ "Third", 0 },
{ "Fourth", 0 }
};
return View(model);
}
HttpPost
public ActionResult DictionaryView(Dictionary<string, int> dictionary)
{
return null;
}
HTML
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<System.Collections.Generic.IDictionary<string,int>>" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<h2>Dictionary</h2>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<% for (int i = 0; i < Model.Count; i++) { %>
**// This is there I am stuck!**
<% } %>
<p>
<input type="submit" value="Submit" />
</p>
<% } %>
</asp:Content>
,
Example
<%
int i = 0;
foreach (KeyValuePair<string, int> pair in Model)
{ %>
<p>Key: <%= Html.TextBox(String.Format("{0}.key", i), pair.Key)%></p>
<p>Value: <%= Html.TextBox(String.Format("{0}.value", i), pair.Value)%></p>
<%
i++;
}
%>
Edit: This should work
,
Can you use a ViewModel (POCO) instead of a Dictionary? That way your model will have something you can select.
EDIT
ok. So my chops aren’t perfect without intellisense… sorry. But this is my general idea
Public Function DictionaryView() As ActionResult
Dim model = New System.Collections.Generic.List(Of MyDictionary)
model.Add(new MyDictionary("First", 0))
model.Add(new MyDictionary("Second", 0))
model.Add(new MyDictionary("Third", 0))
model.Add(new MyDictionary("Forth", 0))
Return View(model)
End Function
''# This would be your view model.
Public Class MyDictionary
Public Property TheString
Public Property TheInt
End Class
Then in your view you can use
model.TheString
model.TheInt
,
Stacey,
I don’t believe the ModelBinder (the default one anyway), will be able to figure out what you’re trying to do, hence the IDictionary param being null.
Your items will be there in the Request.Params collection. For example:
Request.Params"First"
will return whatever you entered in the first text box. From there, you can pluck them out by hand.
If you want to make this work without using a ViewModel as @rockinthesixstring suggested, you are most likely going to have to write a custom ModelBinder that would do what you want.
If you need an example of this, let me know and I’ll dig up the custom model binder stuff.
BTW, a working view can look like this:
foreach (var pair in Model)
{
Response.Write(Html.TextBox(pair.Key, pair.Value));
}
,
You are missing the concept of how to have a separate counter so you have an index and also iterate through the dictionary with a foreach loop:
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<% int counter = 0;
foreach (var kv in Model) { %>
<input type="text" name="dictionary<%= counter %>.Key" value="<%= kv.Key %>" />
<input type="text" name="dictionary<%= counter %>.Value" value="<%= kv.Value %>" />
<%
counter++;
} %>
<p>
<input type="submit" value="Submit" />
</p>
<% } %>
Just tested this now, my Controller is a CCP of yours.
And FYI I simply read that blog post to get here. You just had to match your html elements to exactly what Scott posted.