MVC3服务层验证。返回异常,自定义对象,模型状态字典?

时间:2011-04-16 06:28:49

标签: asp.net-mvc model-view-controller asp.net-mvc-3

对您在服务层验证方面的想法或经验感到好奇。

我必须处理相当标准的验证,例如“具有name属性的对象尚不存在”,但我不确定如何将这些验证失败返回给控制器。

我最初的想法是实施一个标准List<ValidationError>,但我已经看到它每一个方面都做了,所以很好奇每个方面的利弊。

感谢您的任何意见。

2 个答案:

答案 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。此方法将允许您在一个例外中捕获所有错误,而不是在服务层捕获所有错误。