本文介绍了使用异常的业务逻辑验证的Asp.net MVC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于我使用在asp.net mvc的做业务规则的验证方法的问题。

I have a question regarding the method i am using for doing Business Rule Validations in asp.net mvc.

目前我有一个异常类,看起来像这样

Currently i have an exception class that looks something like this

public class ValidationException : Exception
{
    private ModelStateDictionary State { get; set; }
    public ValidationException(ModelStateDictionary state)
    {
        State = state;
    }
    public void MergeModelStates(ModelStateDictionary state)
    {
        state.Merge(this.State);
    }
}

和看起来像这样的验证

public void Validate(IEntity entity)
{
    ModelStateDictionary state = new ModelStateDictionary();
    if (entity.Contact != null && _service.GetBy(entity.Contact.Id) == null)
        state.AddModelError("Contact", "Invalid Contact.");
    if (entity.Title.Length > 8)
        state.AddModelError("title", "Title is too long...");
    ... etc
    if (!state.IsValid)
        throw new ValidationException(state);
}

和一个控制器,做这样的事情。

and a Controller That does something like this

public ActionResult Add()
{
    var entity = new InputModel;
    try
    {
        TryUpdateMode(inputModel);
        ..... Send input to a Repository (Repository calls Validate(entity);
    }
    catch (ValidationException validationException)
    {
       validationException.MergeModelStates(this.ModelState);
       TryUpdateModel(inputModel);
       return View("Add",inputModel);
    }
    return View("List");
}

这是错误的使用异常做这样的事情?
是否有更好的方法的例子吗?我真的不希望验证添加到模型实体本身。唯一的其他方式,我已经看到了它所做的是ModelState中注入控制器到存储库层,但似乎马虎给我。

Is it wrong to use an exception to do something like this?Are there examples of a better method? I don't really want to add the validation to the Model Entity itself. The only other way i've seen it done is to inject the Controllers ModelState to the Repository layer, but that seemed sloppy to me.

感谢您的帮助。

推荐答案

例外一般应为特殊情况下,并没有处理的东西,可能你的程序的正常执行过程中经常发生。有很多很好的原因 - 这里的一些我碰到的相当定期:

Exceptions should generally be for exceptional cases, and not to handle something that could routinely happen during normal execution of your program. There's a lot of good reasons for this - here's some I've run into fairly regularly:


  1. 性能问题 - 例外通常是相当昂贵的操作 - 如果他们抛出的定期业绩可能会受到影响

  2. 与未捕获的验证异常处理 - 在你碰巧使用code无需处理异常事件,你会尽量为黄色屏幕或崩溃处理表面的验证错误了 - 可能不是最好的用户体验。

  3. 例外还没有的方式,允许良好的面向用户的信息构成。看一看异常类 - 没有多少有被设置的方式,使得良好的面向用户的信息,那么你会需要将信息传递给用户。任何时候,我试图以这种方式我已经结束了与子类的一大堆与上涨在不真正使很多学生属于一个例外感属性使用异常。

一的方法,我通常喜欢做的是提供一个公共验证方法,返回的错误的列表(但从未抛出异常本身),然后它调用验证(Save方法),如果有任何抛出一个异常错误。您可以从扔如果模型无效到扔如果code试图保存,而模型处于无效状态切换行为。

One approach I usually like to do is to provide a public Validate method that returns a list of errors (but never throws an exception itself), and then a Save method which calls Validate() and throws an exception if there are any errors. You switch the behavior from "throw if the model isn't valid" to "throw if the code tries to save while the model is in an invalid state".

要解决以下有关业绩的注释中验证与保存抛出 - 在保存抛()将拥有完全相同的性能损失为验证抛()。然而,关键的区别是,这绝不应该发生 - 你使用你的类不正确,而不是使用异常作为验证方法防范开发商。正确地编写,code调用保存的方法应该是这个样子:

To address the comment below regarding performance of throws in Validate vs. Save - throwing in Save() will have the exact same performance penalty as throwing in Validate(). The key difference however is that this should never happen - you're guarding against a developer using your classes improperly rather than using exceptions as a validation method. Properly written, code that calls the save method should look something like:

ValidationResult result = obj.Validate();
if (result.IsValid) {
   obj.Save();
} else {
   // display errors to the user
}

如果开发人员忘记保存前检查验证状态的异常只会被抛出。这具有两个允许验证的益处,而不使用异常,以及从不允许保存无效实体保护数据库的情况发生。理想情况下,你不会赶在控制器异常都让一般错误处理程序处理它,因为这个问题已经不再是用户输入的,而是开发商的错。

The exception would only be thrown if the developer forgot to check the validation status before saving. This has the benefit of both allowing validation to happen without using exceptions, as well as protecting your database by never allowing invalid entities to be saved. Ideally you wouldn't catch the exception in the controller at all and let general error handling routines deal with it, since the problem is no longer with user input but instead the fault of the developer.

这篇关于使用异常的业务逻辑验证的Asp.net MVC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-27 23:51