当您在ASP.NET MVC中使用强类型帮助程序(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>
我为我的观点声明了模型:
@model TestProjects.ViewModels.PersonCreateViewModel
最后,控制器中的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_address等。
那么我应该只更改http post控制器mehtod中的Bind属性来反映这一点吗?但是,如果我更改此属性,属性将不再与导致断开连接的person对象匹配。
或者我应该更改我的视图模型?而不是让人在我的ViewModel中键入,将模型中的所有字段复制/粘贴到ViewModel中?我想这也可以,但这是它的典型方式吗?如果视图模型中的模型只有一个实例,那么列出模型的每个属性似乎是多余的?
答案 0 :(得分:4)
在视图中,我使用model.person.address引用模型的属性。这是正确的方法吗?我注意到,当它生成html时,它将字段命名为person_address等。
是的,这是引用模型属性的正确方法。更准确地说,由于助手表达式中的model
是对Func
输入参数的引用,因此它可以是任何内容。以下也适用:
@Html.EditorFor(banana => banana.person.address)
那么我应该只更改http post控制器mehtod中的Bind属性来反映这一点吗?但是,如果我更改此属性,属性将不再与导致断开连接的person对象匹配。
根本不需要绑定参数。你应该做的是完全从你的视图模型中引用你的数据实体(即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
}