在 HttpModule 中引发异常时 ASP.NET MVC 中的自定义错误消息



我正在使用 ASP.NET MVC。我将任何未经处理的异常捕获在OnException BaseController以正确显示好消息。

但是,我在同一解决方案中有一个 Http 模块项目。如果用户发出错误的请求,模块可能会抛出InvalidOperationException。我正在使用IIS7集成模式,并且所有配置都已正确。我是 IIS 生命周期和 Http 模块异常的新手。

谷歌搜索只找到了使用HttpMethod进行异常处理的方法,这与这种情况不同。

问题是,如果模块中抛出了异常,MVC 是否会执行?如果是这样,为什么它不会OnException?以及如何像操作方法一样在 MVC 中获取异常?

编辑:基于有关应用程序生命周期的答案@nickvane,我尝试更好地解释这种情况。我认为即使是我创建的任何HttpModule都可能引发任何异常。我希望此异常由我的 MVC 处理,该 MVC 在 UrlRoutingModule .我正在考虑一个:

  • HttpModule 的顺序
  • 未处理的异常会停止模块,下一个模块永远不会运行?
  • 如何处理MVC Web应用程序(UrlRoutingModule)中的异常,如果只是在UrlRoutingModule之前或之后执行的另一个HttpModule中抛出。
  • 我可以使用 context.AllErrorscontext.Error 获取另一个模块中引发的异常吗?但我无法得到错误。

我在地球上发现的唯一方法是从抛出异常更改为Server.Transfer()但是其他不属于我的模块怎么样,它仍然抛出异常,我想抓住它。

想想看:我创建了MVC Restful API,它必须返回一个JSON。我可以使用 OnException 正确处理 MVC 应用程序中的任何异常,以便任何未处理的异常都会返回类似 {"错误":"此处的错误消息。现在我有 HttpModule 可能会抛出错误。该模块不关心 API 和 JSON,它只是抛出异常。然后我尝试在 MVC 中捕获此异常以 JSON 格式返回。

控制器或 httpmodule 的生命周期非常不同。此链接显示 asp.net 应用程序的生命周期:

http://msdn.microsoft.com/en-us/library/bb470252.aspx

虽然它不是专门针对 asp.net mvc,但 mvc 框架插入到此生命周期并遵循以下管道:

http://ajaxus.net/wp-content/uploads/2010/01/asp_net_mvc_poster.pdf

从 http://www.asp.net/mvc/tutorials/understanding-the-asp-net-mvc-execution-process-vb

对基于 MVC ASP.NET Web 的请求 应用程序首先通过 UrlRoutingModule 对象,它是一个 HTTP 模块。此模块解析 请求并执行路由选择。 对象选择 匹配的第一个路由对象 当前请求。(路由对象 是一个实现 RouteBase 的类, 并且通常是 路由类。如果没有匹配的路由,则 UrlRoutingModule 对象不执行任何操作 并让请求回退到 常规 ASP.NET 或 IIS 请求 加工。

从选定的路由对象中, UrlRoutingModule 对象获取 IRouteHandler 对象是 与路由对象关联。 通常,在 MVC 应用程序中,这 将是 MvcRouteHandler.The IRouteHandler 实例创建一个 IHttpHandler 对象并向其传递 IHttpContext 对象。默认情况下,IHttp处理程序 MVC 的实例是 MvcHandler 对象。然后 MvcHandler 对象 选择将 最终处理请求。

HttpModule 插入应用程序生命周期,可以在控制器实例化之前或释放之后执行代码,具体取决于它从应用程序生命周期处理的事件。因此,它不能使用控制器的异常处理。

如果您想正确处理 httpmodule 中的异常,我认为您有 2 个选择:

  1. 捕获异常时,可以更改请求的响应。您可以插入错误div 或用错误消息替换整个响应,或者只记录异常。在此方案中,请求将遵循管道的其余部分。
  2. 或者,您可以引发异常并在 global.asax Application_Error 方法中处理它。在此方案中,不会执行控制器。

如果 HttpModule 抛出有效的异常,那么我会选择选项 2。您可以抛出自己的自定义异常,并在 global.asax 中以不同的方式处理它,甚至可以返回 HTTP 响应(400 错误请求)。

更新

如果在 HttpModule 中引发异常,Application_Error 方法将捕获该异常。我尝试了以下有效的代码片段,尽管感觉不对:

protected void Application_Error()
    {
        var ex = Server.GetLastError(); // get the last exception that was made
        if (ex == null) return; // if there is no exception, just continue
        Response.ClearContent();
        Response.Write("{'error':'" + ex.Message + "'}");
        Response.ContentType = "application/json";
        Response.Flush(); // flush the content to the client
        Response.Close(); // and close the connection so that no other content can be written to the response
        Server.ClearError(); // clear the error so that asp.net does not use the custom error page. If we don't close the response and clear the error, the request will still be handled in the rest of the pipeline.
    }

最新更新