我们总是被告知 aController
应该是瘦的,并且应该在 中进行验证Model
,而不是在Controller
. 但请考虑以下示例。
这是一个简单Model
的Controller
用于处理POST
来自编辑屏幕的操作,我们可以在该屏幕上编辑Person
对象。
public class PersonEditModel
{
[Required(ErrorMessage = "No ID Passed")]
public int ID { get; set; }
[Required(ErrorMessage = "First name Required")]
[StringLength(50,ErrorMessage = "Must be under 50 characters")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last name Required")]
[StringLength(50,ErrorMessage = "Must be under 50 characters")]
public string LastName { get; set; }
}
public class PersonController : Controller
{
// [HttpGet]View, [HttpGet]Edit Controller methods omitted for brevity
[HttpPost]
public ActionResult Edit(PersonEditModel model)
{
// save changes to the record
return RedirectToAction("View", "Person", new { ID = model.ID});
}
}
这里Model
执行两种验证。它验证FirstName
and LastName
,但它也ID
验证用于访问我们希望更改的记录的私钥 ( )。是否也应在此验证中进行Model
?
如果我们想要扩展验证(正如我们应该的那样)包括检查这条记录是否存在,该怎么办?
通常,我会在控制器中验证这一点:
[HttpPost]
public ActionResult Edit(PersonEditModel model)
{
using(DatabaseContext db = new DatabaseContext())
{
var _person = db.Persons.Where(x => x.ID == model.ID);
if(_person == null)
{
ModelState.AddError("This person does not exist!");
// not sure how we got here, malicious post maybe. Who knows.
// so since the ID is invalid, we return the user to the Person List
return RedirectToAction("List", Person");
}
// save changes
}
// if we got here, everything likely worked out fine
return RedirectToAction("View", "Person", new { ID = model.ID});
}
这是不好的做法吗?我是否应该检查模型中某种复杂的自定义验证方法中是否存在记录?我应该把它完全放在其他地方吗?
更新
在相关说明上。是否应该ViewModel
包含填充数据的方法?
其中哪一个是更好的做法 - 这个
public class PersonViewModel
{
public Person person { get; set; }
public PersonViewModel(int ID){
using(DatabaseContext db = new DatabaseContext())
{
this.person = db.Persons.Where(x => x.ID == ID);
}
}
}
[HttpPost]
public ActionResult View(int ID)
{
return View("View", new PersonViewModel(ID));
}
或这个?
public class PersonViewModel
{
public Person person { get; set; }
}
[HttpPost]
public ActionResult View(int ID)
{
PersonViewModel model = new PersonViewModel();
using(DatabaseContext db = new DatabaseContext())
{
model.person = db.Persons.Where(x => x.ID == ID);
}
return View("View", model);
}