使用模型绑定从MVC 4中的List <T>中选择项目

Eri*_* J. 5 asp.net-mvc model-binding asp.net-mvc-4

给一个班级

public class Person
{
    // Some general properties

    public List<Hobby> Hobbies { get; set; }
}

public class Hobby
{
    // Some properties e.g. Name, etc.
}

static List<Hobby> AllHobbies { get; }
Run Code Online (Sandbox Code Playgroud)

是否可以创建一个允许用户使用模型绑定选择他的爱好的视图?

在视图中肯定可以循环AllHobbies并渲染<input type="checkbox" />每个,然后在回发控制器中手动连接所选值.这似乎应该可以用模型绑定,但我不知道如何.

Dar*_*rov 11

当然,我建议你使用编辑器模板.

假设一个爱好有一个名字和一个布尔字段,表明它是否被用户选中:

public class Hobby
{
    public string Name { get; set; }
    public bool Selected { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后是一个控制器将模型提供给视图并处理表单提交:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var person = new Person
        {
            Hobbies = new[]
            {
                new Hobby { Name = "hobby 1" },
                new Hobby { Name = "hobby 2", Selected = true },
                new Hobby { Name = "hobby 3" },
            }.ToList()
        };
        return View(person);
    }

    [HttpPost]
    public ActionResult Index(Person person)
    {
        var selectedHobbies = person
            .Hobbies
            .Where(x => x.Selected).Select(x => x.Name);
        string message = string.Join(",", selectedHobbies);
        return Content("Thank you for selecting: " + message);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后是一个包含允许用户选择爱好的表单的视图:

@model Person

@using (Html.BeginForm()) 
{
    <h2>Hobbies</h2>
    @Html.EditorFor(x => x.Hobbies)
    <button type="submit">OK</button>
}
Run Code Online (Sandbox Code Playgroud)

以及相应的编辑器模板,它将自动为Hobbies集合的每个元素呈现(~/Views/Home/EditorTemplates/Hobby.cshtml- >注意模板的名称和位置很重要):

@model Hobby

<div>
    @Html.LabelFor(x => x.Selected, Model.Name)
    @Html.HiddenFor(x => x.Name)
    @Html.CheckBoxFor(x => x.Selected)
</div>
Run Code Online (Sandbox Code Playgroud)

对于更高级的编辑方案,我建议您浏览Steven Sanderson 关于此主题的博客文章.

  • 不,您的错误在于您将域模型传递给您的视图.这是错的.您应该定义视图模型.在此视图模型中,您将拥有一个布尔"Selected"属性,该属性允许您使用视图中的复选框并由用户获取所选值.然后,您将结果映射到您的域模型,以执行您需要执行的任何操作.记住MVC中最重要的规则:控制器操作仅向视图传递视图模型/从视图中获取视图模型.不是域名模型.视图模型是您专门设计的类,以满足给定视图的要求. (4认同)
  • 不,直接从域模型派生视图模型是一个非常糟糕的主意.不要这样做. (2认同)