简体   繁体   English

Asp.net Web表单中的MVC异常过滤器等效项

[英]MVC Exception Filter equivalent in Asp.net web forms

In MVC Web Forms, we have the error Filter by impementing IExceptionFilter. 在MVC Web窗体中,通过添加IExceptionFilter会出现错误Filter。 This ensures that any exception in the application will be routed here. 这样可以确保将应用程序中的任何异常都路由到此处。

Is there an equivalent for this in ASP.Net? 在ASP.Net中有与此等效的功能吗? Is the Application_Error method invoked for all exceptions? 是否为所有异常调用了Application_Error方法?

First, you should check through the official documentation. 首先,您应该检查官方文档。

You're asking about Web Forms, and then referring to ASP.NET, so I'm not really sure if you're asking about MVC or something else, but I am going to assume MVC. 您先问Web表单,然后再指ASP.NET,所以我不确定是否要问MVC或其他问题,但是我将假设MVC。 1 & 3 apply regardless. 1&3适用。

I found a nice Stackify article that is more condensed, which I'll paraphrase here. 我找到了一篇更精简的Stackify文章 ,我将在这里予以解释。 I'm going to ignore error handling that is not a global solution (HandleErrorAttribute, etc). 我将忽略不是全局解决方案的错误处理(HandleErrorAttribute等)。

Depending on your needs, there are a few options for dealing with unhandled exceptions: 根据您的需求,有一些选项可以处理未处理的异常:

1) Generic Erorr pages configured in Web.Config section 1)在Web.Config部分配置的通用Erorr页面

<system.web>
    <customErrors mode="On" defaultRedirect="~/ErrorHandler/Index">
        <error statusCode="404" redirect="~/ErrorHandler/NotFound"/>
    </customErrors>
<system.web/>

If you set up something similar to the code above (replacing the example paths with paths to your error handler or other web pages), you can set up a default error page, as well as error pages for each type of status code. 如果设置与上面的代码类似的内容(将示例路径替换为错误处理程序或其他网页的路径),则可以设置默认错误页面以及每种状态码的错误页面。 If you set mode="RemoteOnly", you'll only see these custom error pages when not on localhost, which can be very useful for debugging. 如果设置mode =“ RemoteOnly”,则仅当不在localhost上时才会看到这些自定义错误页面,这对于调试非常有用。

For example, I have the following in my project: 例如,我的项目中包含以下内容:

<customErrors mode="RemoteOnly" defaultRedirect="/ErrorHandler">
  <error statusCode="400" redirect="~/ErrorHandler/?errorCode=400" />
  <error statusCode="401" redirect="~/ErrorHandler/?errorCode=401" />
  <error statusCode="403" redirect="~/ErrorHandler/?errorCode=403" />
  <error statusCode="404" redirect="~/ErrorHandler/?errorCode=404" />
  <error statusCode="500" redirect="~/ErrorHandler/?errorCode=500" />
</customErrors>

This means that any generic exception with those status codes is automatically handles for me. 这意味着带有这些状态代码的任何通用异常都会自动为我处理。 ErrorHandler is a simple controller I created for this. ErrorHandler是我为此创建的一个简单控制器。 However, this does not allow you to execute code on an unhandled exception, just display a generic error page. 但是,这不允许您在未处理的异常上执行代码,仅显示一般错误页面。

2) Override OnException function on Controller 2)在控制器上重写OnException函数

This requires you to set up an interface class for your controllers and to develop an override method for the controller's OnException method. 这要求您为控制器设置接口类,并为控制器的OnException方法开发重写方法。

From the Stackify article, they develop a class named UserMvcController that inherits from Controller. 他们从Stackify文章中开发了一个名为UserMvcController的类,该类继承自Controller。 I personally have a class named IBaseController that has this method, along with other methods, overridden. 我个人有一个名为IBaseController的类,该类具有重写此方法以及其他方法的方法。

An example of a simple interface: 一个简单的界面示例:

public class UserMvcController : Controller
{
   protected override void OnException(ExceptionContext filterContext)
   {
      filterContext.ExceptionHandled = true;

      //Log the error!!
      _Logger.Error(filterContext.Exception);

      //Redirect or return a view, but not both.
      filterContext.Result = RedirectToAction("Index", "ErrorHandler");
      // OR 
      filterContext.Result = new ViewResult
      {
         ViewName = "~/Views/ErrorHandler/Index.cshtml"
      };
   }
} 

An example from one of my projects with a few other functions. 我的一个项目中的示例具有其他一些功能。 All of these functions are available on your controllers if your controllers inherit from your base class: 如果控制器从基类继承,则所有这些功能在控制器上都可用:

public class IBaseController : Controller
{
    // Function to set up modal pup with Error styling
    public void Error(string errorHeader, string errorMessage)
    {
        ViewBag.ErrorHeader = errorHeader;
        ViewBag.ErrorMessage = errorMessage;
        ViewBag.JavaScriptHandler = "ShowErrorModal();";
    }

    // Function to set up modal pup with Informational styling
    public void Info(string infoHeader, string infoMessage)
    {
        ViewBag.InfoHeader = infoHeader;
        ViewBag.InfoMessage = infoMessage;
        ViewBag.JavaScriptHandler = "ShowInfoModal();";
    }

    // Function to override OnException method to pass exception info the ErrorController
    protected override void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;

        //Redirect or return a view, but not both.
        filterContext.Result = RedirectToAction("Message", "ErrorHandler", new { area = "", errorException = filterContext.Exception.Message });
    }
}

As you can see, my OnException override simply passes some of the exception information to another controller to handle. 如您所见,我的OnException重写只是将一些异常信息传递给另一个控制器进行处理。 I do not use it to log or trace anything. 我不使用它来记录或跟踪任何内容。 If you're using a controller, this method will be called on all unhandled exceptions. 如果您使用的是控制器,则会在所有未处理的异常上调用此方法。

3) Use Application_Error 3)使用Application_Error

In your Global.asax file, you can also set up the Application_Error() function to handle errors. 在Global.asax文件中,您还可以设置Application_Error()函数来处理错误。

public class MvcApplication : System.Web.HttpApplication
{
   protected void Application_Start()
   {
      AreaRegistration.RegisterAllAreas();
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
      RouteConfig.RegisterRoutes(RouteTable.Routes);
      BundleConfig.RegisterBundles(BundleTable.Bundles);
   }

   protected void Application_Error()
   {
      var ex = Server.GetLastError();
      //log the error!
      _Logger.Error(ex);
   }
}

This will allow you to do simple logging and generic types of error handling. 这将允许您执行简单的日志记录和错误处理的常规类型。 I suppose you can implement something very robust here, but I prefer to do most of my logical handling within the controller. 我想您可以在这里实现非常强大的功能,但是我更喜欢在控制器中进行大部分逻辑处理。

Closing Remark 闭幕致辞

Personally, I prefer overriding the OnException method of the controller and handling my errors through there. 就个人而言,我更喜欢覆盖控制器的OnException方法并通过该方法处理我的错误。 I've found that by using that, and a well developed controller to handle errors, you can do some powerful things. 我发现通过使用它以及完善的控制器来处理错误,您可以做一些有力的事情。 There are even more options than these, but I think this will get you started. 还有更多选择,但是我认为这可以帮助您入门。

Best. 最好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM