【问题标题】:ASP.Net MVC 2 - ModelBinding and Dictionary<int, int>ASP.Net MVC 2 - ModelBinding 和 Dictionary<int, int>
【发布时间】:2014-02-07 17:32:01
【问题描述】:

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

非常感谢您的帮助

【问题讨论】:

    标签: asp.net-mvc-2 idictionary model-binding


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      好的...感谢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,有一个更清洁的解决方案。

      在控制器代码中,使用可为空的 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);
          }
      

      【讨论】:

      • 试试public ActionResult Save(int? id, Dictionary&lt;int, int?&gt; cbts)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多