Asp.net mvc 从列表中选择项目<;T>;在MVC4中使用模型绑定

Asp.net mvc 从列表中选择项目<;T>;在MVC4中使用模型绑定,asp.net-mvc,asp.net-mvc-4,model-binding,Asp.net Mvc,Asp.net Mvc 4,Model Binding,上课 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; } 公共类人物 { //一些一般性质 公共列表爱好{get;se

上课

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; }
公共类人物
{
//一些一般性质
公共列表爱好{get;set;}
}
公共课爱好
{
//一些属性,例如名称等。
}
静态列表所有爱好{get;}
是否可以创建一个视图,允许用户使用模型绑定选择他的爱好


在视图中,当然可以循环通过
所有爱好
,并为每个爱好呈现一个
,然后在回发控制器中手动连接选定的值。似乎这在模型绑定中是可行的,但我不知道如何做到。

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

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

public class Hobby
{
    public string Name { get; set; }
    public bool Selected { get; set; }
}
然后是一个控制器,用于将模型输入视图并处理表单提交:

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);
    }
}
然后是一个包含表单的视图,允许用户选择爱好:

@model Person

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

对于更高级的编辑场景,我建议您阅读Steven Sanderson关于此主题的文章。

+1,非常好的信息。但是,
Hobby
类没有(也不应该)布尔值,指示特定用户是否从域模型的角度选择了它(当然这是一个简化的示例)。我是否必须向对象添加一个临时布尔字段来支持这一点,或者是否有其他方法在没有该额外字段的情况下进行绑定?否,您的错误是将域模型传递给视图。这是错误的。您应该定义一个视图模型。在该视图模型中,您将拥有一个布尔
Selected
属性,该属性允许您使用视图中的复选框,并由用户获取所选值。然后,您将把结果映射到您的域模型,以执行您需要对其执行的任何操作。记住MVC中最重要的规则:控制器操作只向视图传递/获取视图模型。而不是域模型。视图模型是您专门为满足给定视图的要求而设计的类。您能否推荐一种模式,以便在域模型和视图模型之间高效地(如在花时间编写和测试)映射?这实际上是第一个实例(尽管我很少进行UI开发),两者之间存在任何差异。您也可以直接从模型派生视图模型并添加所需的属性。不,直接从域模型派生视图模型是一个非常糟糕的主意。不要这样做。
@model Hobby

<div>
    @Html.LabelFor(x => x.Selected, Model.Name)
    @Html.HiddenFor(x => x.Name)
    @Html.CheckBoxFor(x => x.Selected)
</div>