将KeyValuePair绑定到复选框列表

Ani*_*man 3 binding asp.net-mvc-2

我在C#中使用ASP.Net MVC.我有一个模型,其中包含筛选条件的成员.该成员是IList>.该键包含要显示的值,该值表示是否选择了此过滤器.我想将它绑定到我的视图上的一堆复选框.这就是我做到的.

<% for(int i=0;i<Model.customers.filterCriteria.Count;i++) { %>
<%=Html.CheckBoxFor(Model.customers.filterCriteria[i].value)%>&nbsp;
<%=Model.customers.filterCriteria[i].key%>
<% } %>
Run Code Online (Sandbox Code Playgroud)

这会正确显示所有复选框.但是当我在控制器中提交我的表单时,无论我在视图中选择什么,我都会为filtercriteria获取null.

这篇文章中我得到了一个创建单独属性的提示.但这对IList如何有效?有什么建议吗?

Dar*_*rov 6

KeyValuePair<TKey, TValue>结构的问题在于它具有私有setter,这意味着默认模型绑定器无法在POST操作中设置它们的值.它有一个特殊的构造函数,需要使用它来传递键和值,但当然默认的模型绑定器不知道这个构造函数,它使用默认的一个,所以除非你为这种类型编写自定义模型绑定器将无法使用它.

我建议您使用自定义类型而不是KeyValuePair<TKey, TValue>.

因此,我们始终以视图模型开始:

public class Item
{
    public string Name { get; set; }
    public bool Value { get; set; }
}

public class MyViewModel
{
    public IList<Item> FilterCriteria { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后一个控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            FilterCriteria = new[] 
            {
                new Item { Name = "Criteria 1", Value = true },
                new Item { Name = "Criteria 2", Value = false },
                new Item { Name = "Criteria 3", Value = true },
            }
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        // The model will be correctly bound here
        return View(model);
    }
}
Run Code Online (Sandbox Code Playgroud)

和相应的~/Views/Home/Index.aspx观点:

<% using (Html.BeginForm()) { %>
    <%= Html.EditorFor(x => x.FilterCriteria) %>
    <input type="submit" value="OK" />
<% } %>
Run Code Online (Sandbox Code Playgroud)

最后我们写在项目类型的自定义编辑模板~/Views/Shared/EditorTemplates/Item.ascx~/Views/Home/EditorTemplates/Item.ascx(如果这个模板是只有特定的家庭控制器,而不是重复使用):

<%@ Control 
    Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.Item>" 
%>
<%= Html.CheckBoxFor(x => x.Value) %>
<%= Html.HiddenFor(x => x.Name) %>
<%= Html.Encode(Model.Name) %>
Run Code Online (Sandbox Code Playgroud)

我们已经完成了两件事:从丑陋的for循环中清理视图,并使模型绑定器成功绑定POST操作中的复选框值.