【发布时间】:2013-11-08 16:39:29
【问题描述】:
我们总是被告知Controller 应该是瘦的,并且验证应该在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 和 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);
}
【问题讨论】:
-
你在最后一个例子中所做的并不是我所说的验证。
PersonEditModel仍然有效。问题是这个人不存在。这是一个不同的错误,并且在控制器中得到了正确处理。 -
看起来不错,没有问题。如果有人说不,请询问原因:)
-
那么这个应该在控制器中吗?
-
我没有发现任何问题,我就是这样做的。但我可能是错的。我会在另一个函数(FindPersonByID)中替换查找人员代码。然后你可以在控制器中调用它并抛出异常,否则调用 save 方法。
-
这对CodeReview来说不是一个更好的话题吗?
标签: c# asp.net asp.net-mvc validation