使用HTML帮助程序通过键将MVC模型绑定到字典

时间:2015-07-27 21:13:44

标签: c# asp.net-mvc dictionary model-binding

在MVC(4)中过滤数据列表时,我将几个过滤器输入绑定到ViewModel模型中的字典。

我已经能够通过这样的输入的文字声明(.aspx引擎)来做到这一点:

 <input type="text" name='Model.Filters[matchId].Filter' 
                    value='<%: Model.Filters["matchId"].Filter %>' />

where&#34; matchId&#34;是要过滤的列的名称。 Model.Filter字典定义为

IDictionary<string,FilterObject>

暂时使用FilterObject:

[Serializable]
public class FilterObject
{
    public FilterObject()
    {
        Filter = "";
    }
    public FilterObject(String value)
    {
        Filter = value;
    }
    //[DefaultValue("")]
    public String Filter { get; set; }
}

所以 - 只要使用Filter输入的所有键初始化Model.Filters Dictionary,它就会起作用,否则我们自然会得到一个未找到的键#34;运行时异常。

将列名字符串硬编码到控制器中很难看,感觉应该可以使用@ Html.TextBoxFor&lt;&gt;(....)来避免异常,但我找不到有效的语法(或者不会破坏无效的索引对象类型等),例如:

Html.TextBoxFor(m=>m.Filters.FirstOrDefault(k=>k.Key=="matchId").Value.Filter)

制作

的HTML
  <input id="Value_Filter" name="Value.Filter" type="text" value="" />

显然没有任何用处

我很确定我只是遗漏了一些东西,但我找到的所有字典绑定示例都依赖于循环并绑定到一个int索引,而我在这一点上难以理解,没有写一个自定义看起来有点过分的助手。

非常感谢任何帮助: - )

1 个答案:

答案 0 :(得分:1)

哈!我停止了对抗潮流并为此写了一个助手,比我想象的更容易:

public static MvcHtmlString TextBoxForFilterDictionary(this HtmlHelper helper, IDictionary<string, FilterObject> filters, string fieldName, object htmlAttributes = null)
    {
        FilterObject filter;
        if (!filters.TryGetValue(fieldName, out filter))
        {
            filter = new FilterObject();
        }
        string nameAttribute = String.Format("Model.Filters[{0}].Filter", fieldName);
        MvcHtmlString html = helper.TextBox(nameAttribute, filter.Filter, htmlAttributes);
        return html;
    }

在HTML中:

  <%: Html.TextBoxForFilterDictionary(Model.Filters, "matchId")%>
  <!-- a bunch of other formatting HTML -->
  <%: Html.TextBoxForFilterDictionary(Model.Filters, "matchName")%>
  <!-- and so on -->

我的通用ViewModel现在可以提供列表排序,分页和过滤所需的所有内容,不需要过滤字典初始化,也不需要看到弱类型的对象。

值得额外的努力!