控制器中的异常处理(ASP.NET MVC) [英] Exception handling in Controller (ASP.NET MVC)

查看:173
本文介绍了控制器中的异常处理(ASP.NET MVC)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当一个异常被你自己的代码抛出,这个代码是从一个控制器的一个动作中调用的,应该如何处理?我看到很多没有try-catch语句的最佳实践的例子。例如,从存储库访问数据:

  public ViewResult Index()
{
IList&&CustomModel> ; customModels = _customModelRepository.GetAll();
return View(customModels);
}

显然,如果调用是对数据库的话,这段代码可能会抛出异常无法访问,我们正在使用像实体框架这样的ORM。



然而,我能看到的一切都将会发生,异常会冒泡起来,表现出令人讨厌的错误消息给用户。



我知道HandleError属性,但我明白,如果发生未处理的异常,它主要用于将您重定向到错误页面。 / p>

当然,这段代码可以包装在一个try-catch中,但并不是很好地分离,特别是如果你有更多的逻辑:

  public ViewResult Index()
{
if(ValidationCheck())
{
IList&&CustomModel> customModels = new List&&CustomModel>();
try
{
customModels = _customModelRepository.GetAll();
}
catch(SqlException ex)
{
//处理异常
}

if(CustomModelsAreValid(customModels))
//做某事
else
//做别的事
}

return View();
}

以前我已经提取出可能会将异常如数据库调用抛出的所有代码DataProvider类处理错误并返回消息,向用户显示消息。



我想知道最好的处理方式是什么?我并不总是希望返回一个错误页面,因为一些异常不应该这样做。相反,应以普通视图显示给用户的错误消息。我以前的方法是否正确或有更好的解决方案?

解决方案

我做了三件事来显示更友好的消息: / p>


  1. 利用全局异常处理程序。在MVC:Global.asax中的Application_Error的情况下。了解如何使用它: http:// msdn.microsoft.com/en-us/library/24395wz3(v=vs.100).aspx

  2. 我将异常子类化为UserFriendlyException。我在我所有的底层服务类中都做得最好,抛出这个UserFriendlyException,而不是一个普通的旧的异常。我总是尝试将这些用户有意义的消息放在这些自定义异常中。其主要目的是能够对Application_Error方法中的异常执行类型检查。对于UserFriendlyExceptions,我只是使用我在服务中设置的用户友好的消息,例如嘿!91度不是有效的纬度值!。如果这是一个常规异常,那么有些情况我还没有处理,所以我会显示一个更通用的错误信息,比如糟糕,出了问题!我们会尽力解决这个问题!

  3. 我还创建一个ErrorController,负责渲染用户友好的视图或JSON。这是控制器,它的方法将从Application_Error方法调用。

编辑:
我以为我会提到ASP.NET Web API,因为它是密切相关的。因为Web API端点的消费者不一定是浏览器,我喜欢处理错误有点不一样。我仍然使用FriendlyException(上面的#2),而不是重定向到一个ErrorController,我只是让我的所有端点返回某种基类型包含一个Error属性。所以,如果一个异常一直发生到Web API控制器,我一定要把这个错误放在API响应的Error属性中。该错误消息将是API控制器所依赖的类中已经冒泡的友好消息,或者如果异常类型不是FriendlyException,则它将是通用消息。这样,消费客户端可以简单地检查API响应的Error属性是否为空。如果错误出现,则显示一条消息,如果没有,请按照惯例进行。好的是,由于友好的消息概念,消息对用户而言可能比通用的错误!更有意义。信息。在使用Xamarin编写移动应用程序时,我可以使用此策略,我可以在我的Web服务和iOS / Android应用程序之间共享我的C#类型。


When an exception is thrown by your own code that's called from an action in a controller how should that be handled? I see a lot of examples of best practices where there are no try-catch statements at all. For example, accessing data from a repository:

public ViewResult Index()
{
    IList<CustomModel> customModels = _customModelRepository.GetAll();
    return View(customModels);
}

Clearly this code could throw an exception if the call is to a database that it can't access and we are using an ORM like Entity Framework for example.

However all that I can see will happen is that the exception will bubble up and show a nasty error message to the user.

I'm aware of the HandleError attribute but I understand it's mostly used to redirect you to an error page if an exception that's unhandled occurs.

Of course, this code could be wrapped in a try-catch but doesn't separate nicely, especially if you have more logic:

public ViewResult Index()
{
    if (ValidationCheck())
    {
        IList<CustomModel> customModels = new List<CustomModel>();
        try
        {
            customModels = _customModelRepository.GetAll();
        }
        catch (SqlException ex)
        {
            // Handle exception
        }

        if (CustomModelsAreValid(customModels))
            // Do something
        else
            // Do something else
    }

    return View();
}

Previously I have extracted out all code that could throw exceptions like database calls into a DataProvider class which handles errors and returns messages back for showing messages to the user.

I was wondering what the best way of handling this is? I don't always want to return to an error page because some exceptions shouldn't do that. Instead, an error message to the user should be displayed with a normal view. Was my previous method correct or is there a better solution?

解决方案

I do three things to display more user-friendly messages:

  1. Take advantage of the global exception handler. In the case of MVC: Application_Error in Global.asax. Learn how to use it here: http://msdn.microsoft.com/en-us/library/24395wz3(v=vs.100).aspx
  2. I subclass Exception into a UserFriendlyException. I do my very best in all of my underlying service classes to throw this UserFriendlyException instead of a plain old Exception. I always try to put user-meaningful messages in these custom exceptions. The main purpose of which is to be able to do a type check on the exception in the Application_Error method. For the UserFriendlyExceptions, I just use the user-friendly message that I've set deep down in my services, like "Hey! 91 degrees is not a valid latitude value!". If it's a regular exception, then it's some case I haven't handled, so I display a more generic error message, like "Oops, something went wrong! We'll do our best to get that fixed!".
  3. I also create an ErrorController that is responsible for rendering user-friendly views or JSON. This is the controller whose methods will be called from the Application_Error method.

EDIT: I thought I'd give a mention to ASP.NET Web API since it's closely related. Because the consumer of Web API endpoints won't necessarily be a browser, I like to deal with errors a little differently. I still use the "FriendlyException" (#2 above), but instead of redirecting to an ErrorController, I just let all my endpoints return some kind of base type that contains an Error property. So, if an exception bubbles all the way up to the Web API controllers, I make sure to stick that error in the Error property of API response. This error message will either be the friendly message that has bubbled up from the classes the API controller relies on, or it will be a generic message if the exception type is not a FriendlyException. That way, the consuming client can simply check whether or not the Error property of the API response is empty. Display a message if the error is present, proceed as usual if not. The nice thing is that, because of the friendly message concept, the message may be much more meaningful to the user than a generic "Error!" message. I use this strategy when writing mobile apps with Xamarin, where I can share my C# types between my web services and my iOS/Android app.

这篇关于控制器中的异常处理(ASP.NET MVC)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆