Asp.net mvc ASP.NET MVC,使用带有强类型帮助程序的viewmodel

Asp.net mvc ASP.NET MVC,使用带有强类型帮助程序的viewmodel,asp.net-mvc,asp.net-mvc-4,Asp.net Mvc,Asp.net Mvc 4,我有一个关于在ASP.NET MVC中使用强类型helpers HTML.EditorFor等和viewmodel时设置viewmodel的问题。我正在使用MVC5,但我想我的问题也适用于其他版本 对于本例,我正在使用CRUD流程的创建 在本例中,用户输入一个人的姓名和地址,并从下拉列表中选择城市 模型如下: public class Person { [Key] public int PersonID { get; set; }

我有一个关于在ASP.NET MVC中使用强类型helpers HTML.EditorFor等和viewmodel时设置viewmodel的问题。我正在使用MVC5,但我想我的问题也适用于其他版本

对于本例,我正在使用CRUD流程的创建

在本例中,用户输入一个人的姓名和地址,并从下拉列表中选择城市

模型如下:

    public class Person
    {
        [Key]
        public int PersonID { get; set; }
        [ForeignKey("City")]
        public int CityID { get; set; }
        public string Name {get; set;}
        public string address {get; set;}

        //Navigational property
        public virtual City City { get; set; }
    }
以下是viewmodel:

public class PersonCreateViewModel
{
    public SelectList cities {get; set;}
    public Person person { get; set; }
}
以下是用于传回创建页面视图的控制器的操作方法:

 public ActionResult Create()
    {
        CreateViewModel viewmodel = new CreateViewModel();

        viewmodel.cities = new SelectList(db.Cities, "CityID", "name");
        return View(viewmodel);
    }
以下是我的部分观点:

        <div class="form-group">
            @Html.LabelFor(model => model.person.name, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
            @Html.EditorFor(model => model.person.name)
            @Html.ValidationMessageFor(model => model.person.name)
        </div>
    </div>

    <div class="form-group">
            @Html.LabelFor(model => model.person.address, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
            @Html.EditorFor(model => model.person.address)
            @Html.ValidationMessageFor(model => model.person.address)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.person.CityID, "CityID", new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("cities")
            @Html.ValidationMessageFor(model => model.person.CityID)
        </div>
    </div>
最后,控制器中的http post方法:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include="PersonID,CityID,nameaddress")] Person person)
    {

        if (ModelState.IsValid)
        {
            //Add to database here and return

        }

        //return back to view if invalid db save
        return View(person);
    }
所以在某一点上,我让所有这些都起作用了。然后我决定使用ViewModel方法。我仍然无法让它工作,但这里有一些问题:

在视图中,我使用model.person.address引用模型的属性。这是正确的方法吗?我注意到,当它生成html时,它命名字段person\u address,等等

那么,我是否应该更改http post控制器方法中的绑定属性来反映这一点?但如果我更改此选项,则属性将不再与导致断开连接的person对象匹配

还是应该更改视图模型?而不是在我的ViewModel中输入person,而是将模型中的所有字段复制/粘贴到ViewModel中?我想这也行,但这是典型的做法吗?列出模型的每个属性似乎是多余的,而如果模型在viewmodel中,我就可以有一个实例

在视图中,我使用model.person.address引用模型的属性。这是正确的方法吗?我注意到,当它生成html时,它命名字段person\u address,等等

是的,这是引用模型特性的正确方法。更准确地说,因为助手表达式中的模型是对Func输入参数的引用,所以它可以是任何东西。以下措施也同样有效:

@Html.EditorFor(banana => banana.person.address)
那么,我是否应该更改http post控制器方法中的绑定属性来反映这一点?但如果我更改此选项,则属性将不再与导致断开连接的person对象匹配

您根本不需要绑定参数。您应该做的是将所有对您的数据实体的引用(即,完全脱离视图模型的人),否则使用视图模型是没有意义的,因为它与您的数据实体紧密耦合,并提供视图所需的视图模型属性,例如:

public class PersonCreateViewModel
{
    public SelectList Cities { get; set; }

    public string Address { get; set; }
    public string Name { get; set; }
    ...
}
然后默认情况下,它们应绑定回同一模型,前提是您的视图是正确的:

public ActionResult Create (PersonCreateViewModel model)
{
    // Map PersonCreateViewModel properties to Person properties
}
在视图中,我使用model.person.address引用模型的属性。这是正确的方法吗?我注意到,当它生成html时,它命名字段person\u address,等等

是的,这是引用模型特性的正确方法。更准确地说,因为助手表达式中的模型是对Func输入参数的引用,所以它可以是任何东西。以下措施也同样有效:

@Html.EditorFor(banana => banana.person.address)
那么,我是否应该更改http post控制器方法中的绑定属性来反映这一点?但如果我更改此选项,则属性将不再与导致断开连接的person对象匹配

您根本不需要绑定参数。您应该做的是将所有对您的数据实体的引用(即,完全脱离视图模型的人),否则使用视图模型是没有意义的,因为它与您的数据实体紧密耦合,并提供视图所需的视图模型属性,例如:

public class PersonCreateViewModel
{
    public SelectList Cities { get; set; }

    public string Address { get; set; }
    public string Name { get; set; }
    ...
}
然后默认情况下,它们应绑定回同一模型,前提是您的视图是正确的:

public ActionResult Create (PersonCreateViewModel model)
{
    // Map PersonCreateViewModel properties to Person properties
}

我明白了,谢谢。我认为使用您的ViewModel版本将使我能够使用绑定参数或像您的操作方法示例中那样映射它们。我注意到有人否决了这个答案。如果有人有解释的话,解释会很有帮助。谢谢我明白了,谢谢。我认为使用您的ViewModel版本将使我能够使用绑定参数或像您的操作方法示例中那样映射它们。我注意到有人否决了这个答案。如果有人有解释的话,解释会很有帮助。谢谢