对您在服务层验证方面的想法或经验感到好奇。
我必须处理相当标准的验证,例如“具有name属性的对象尚不存在”,但我不确定如何将这些验证失败返回给控制器。
我最初的想法是实施一个标准List<ValidationError>
,但我已经看到它每一个方面都做了,所以很好奇每个方面的利弊。
感谢您的任何意见。
答案 0 :(得分:4)
如果您使用System.ComponentModel.DataAnnotations条目,您可以(如您所知)使用必需和更多标签装饰您的属性
public class Person
{
[Required(ErrorMessage="object with name property doesn't already exist")]
public string Name { get; set; }
}
虽然我个人使用ViewModels而不是将域mdoels暴露给视图,但您的控制器操作现在可以执行以下操作:
[HttpPost]
public ActionResult SavePerson(Person model)
{
if (ModelState.IsValid)
{
// your model validates - do things
return RedirectToAction("success view here");
}
return View(model);
}
这是MVC中标准的“post”处理程序模式之一。在我看来,这是让对象模型验证的最简单途径。
从那里,还有一些其他选项 - 您的域对象可以实现IValidatedableObject,您可以yield return
错误(请参阅http://buildstarted.com/2010/09/20/mvc-3s-ivalidatableobject/作为示例)。
我建议不要将两者混合使用,就像使用数据注释并且甚至只有一个无效属性一样,IValidatableObject上的IsValid方法也不会被调用。
从那里开始,您可以使用自定义验证属性(IsValid的扩展版本似乎为您提供了更多的灵活性http://msdn.microsoft.com/en-us/library/gg480674%28v=vs.98%29.aspx)
希望上述一些帮助 - 一旦你完成了基础知识,你可以用它做很多事情,比如客户端验证自定义属性等等都很有趣。
干杯, 特里
[编辑添加:
重新阅读您的帖子后,您可能只想在服务层进行验证?如果是这样,我使用了以下方法:
public void Setname(string newName)
{
Validator.ValidateProperty(newName, new ValidationContext(this, null, null) { MemberName = "Name" });
Name = newName;
}
显然你的Name属性需要一个{ get; private set; }
,尽管你总是可以将Validator.ValidateProperty添加到公共属性的扩展setter中。
答案 1 :(得分:0)
在我正在研究的新项目上(第一次使用mvc)我一直在使用ms代码契约(抛出异常)并对我的域对象本身进行所有验证。对于那里无法验证的事物(例如需要数据库访问的验证),我在我的服务中验证并抛出异常。另外,就像上面的海报一样,我有完整的单独视图模型,可以查看有关数据注释验证器的所有内容。异常冒泡,我在控制器中捕获它们并附加到ModelState。有很多与和视图模型验证重叠的,但它没有多少额外的努力,让我改变按次验证,但仍然有“核心”验证是必要的。
本书pro asp mvc 2有另一种不错的方法 - 编写一个继承Exception并包含错误集合的类。然后你做你的验证,添加到集合然后抛出异常,然后他在控制器中捕获它并复制到ModelState。此方法将允许您在一个例外中捕获所有错误,而不是在服务层捕获所有错误。