在我的界面中,我有一个文本框列表,如下所示: http://screencast.com/t/YjIxNjUyNmU
文本框的数量未知,因为每个文本框都与模板相关联。 在我的页面中,目标是将一个数字与其中一些模板相关联。
以下是HTML代码示例:
<% // 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 />
<% }
%>
我期望在我的控制器中获得一个IDictionary,其中第一个int是模板ID,另一个是用户给出的计数。
这就是我想要的:
public ActionResult Save(int? id, Dictionary<int, int> countByTemplate)
我尝试了很多东西,但没有任何效果。我试图阅读消息来源,但这是一个迷宫,我正在试图获取有关模型绑定的信息。
问题:
非常感谢你的帮助
答案 0 :(得分:1)
有关如何编写输入元素以绑定到数组,字典和其他集合的信息,请访问http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx。
答案 1 :(得分:1)
好的......感谢Levi我能够找到解决方案。 不是更干净的,但它有效。
HTML应该这样写:
<%
int counter = 0;
// loop on the templates
foreach(ITemplate template in templates)
{
// get the value as text
int val;
content.TryGetValue(template.Id, out val);
var value = ((val > 0) ? val.ToString() : string.Empty);
// compute the element name (for dictionary binding)
string id = "cbts_{0}".FormatMe(template.Id);
string dictKey = "cbts[{0}].Key".FormatMe(counter);
string dictValue = "cbts[{0}].Value".FormatMe(counter++);
%>
<input type="hidden" name="<%= dictKey %>" value="<%= template.Id %>" />
<input type="text" id="<%= id %>" name="<%= dictValue %>" value="<%= value %>" />
<label for="<%= id %>"><%= template.Name %></label>
<br />
<% }
%>
我必须添加一个隐藏字段来存储值。 我引入了一个'假'计数器,只是为了按照ASP.Net MVC想要的方式遍历字典。 结果我得到了一个填充了我的值的字典,当文本框为空时我得到了'0'。
出现了另一个问题:ModelState
被认为无效,因为“需要一个值”。我不希望我的值是必需的,但是看看模型绑定器代码,我没有找到告诉绑定器不需要值的方法。
所以我欺骗了我的控制器中的ModelState
,删除了所有错误,如下所示:
public ActionResult Save(int? id, Dictionary<int, int> cbts)
{
// clear all errors from the modelstate
foreach(var value in this.ModelState.Values)
value.Errors.Clear();
嗯...我有效地得到了一个解决方案,但HTML现在有点难看,而且违反直觉(使用索引循环遍历非索引集合?)。 而且每次我都会使用这种绑定来完全正常工作时我需要欺骗。
所以我现在打开一个新帖子,使字典绑定更好。 这是:ASP.Net MVC 2 - better ModelBinding for Dictionary<int, int>
编辑 - 感谢Pavel Chuchuva提供更清洁的解决方案。
在控制器代码中,使用nullable int作为字典的值。 添加更多代码,但更清洁。
public ActionResult Save(int? id, Dictionary<int, int?> cbts)
{
// this is our final dictionary<int, int>
Dictionary<int, int> cbtsFinal = new Dictionary<int, int>();
// loop on the dicitonary with nullable values
foreach(var key in cbts.Keys)
{
// if we have a value
if(cbts[key].HasValue)
// then put it in the final dictionary
cbtsFinal.Add(key, cbts[key].Value);
}