0

在我的界面中,我有一个文本框列表,如下所示: 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)

我尝试了很多东西,但没有任何效果。我试图阅读源代码,但它是一个迷宫,我正在头疼试图获取有关模型绑定的信息。

问题 :

  • 是否有关于模型绑定如何工作的良好资源?我想要一些详尽的内容,我厌倦了讨论给定特定示例的 84093043 博客。
  • 如何构建我的 HTML,用于获取 IDictionary(甚至是控制器操作中的 IDictionary?

非常感谢你的帮助

4

2 回答 2

1

有关如何编写用于绑定到数组、字典和其他集合的输入元素的信息,请访问 http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

于 2010-05-25T18:45:44.010 回答
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 - Dictionary<int, int> 的更好的 ModelBinding

编辑- 感谢 Pavel Chuchuva,有一个更清洁的解决方案。

在控制器代码中,使用可为空的 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);
    }
于 2010-05-26T08:20:49.383 回答