首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Application_Error Global.asax? ASP.NET MVC自定义错误处理?

Application_Error Global.asax? ASP.NET MVC自定义错误处理?
EN

Stack Overflow用户
提问于 2009-07-23 11:07:05
回答 8查看 177.7K关注 0票数 111

我有一些基本代码来确定我的MVC应用程序中的错误。目前在我的项目中,我有一个名为Error的控制器,它具有动作方法HTTPError404()HTTPError500()General()。它们都接受字符串参数error。使用或修改下面的代码。将数据传递到错误控制器进行处理的最佳/适当方法是什么?我希望有一个尽可能健壮的解决方案。

代码语言:javascript
复制
protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Response.Clear();

    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        switch (httpException.GetHttpCode())
        {
            case 404:
                // page not found
                routeData.Values.Add("action", "HttpError404");
                break;
            case 500:
                // server error
                routeData.Values.Add("action", "HttpError500");
                break;
            default:
                routeData.Values.Add("action", "General");
                break;
        }
        routeData.Values.Add("error", exception);
        // clear error on server
        Server.ClearError();

        // at this point how to properly pass route data to error controller?
    }
}
EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-07-23 13:40:28

不需要为此创建新的路由,您只需重定向到您的控制器/操作并通过querystring传递信息即可。例如:

代码语言:javascript
复制
protected void Application_Error(object sender, EventArgs e) {
  Exception exception = Server.GetLastError();
  Response.Clear();

  HttpException httpException = exception as HttpException;

  if (httpException != null) {
    string action;

    switch (httpException.GetHttpCode()) {
      case 404:
        // page not found
        action = "HttpError404";
        break;
      case 500:
        // server error
        action = "HttpError500";
        break;
      default:
        action = "General";
        break;
      }

      // clear error on server
      Server.ClearError();

      Response.Redirect(String.Format("~/Error/{0}/?message={1}", action, exception.Message));
    }

然后你的控制器会收到你想要的任何东西:

代码语言:javascript
复制
// GET: /Error/HttpError404
public ActionResult HttpError404(string message) {
   return View("SomeView", message);
}

你的方法有一些权衡。在这种错误处理中,要非常非常小心地使用循环。另一件事是,由于您要通过asp.net管道来处理404,因此您将为所有这些命中创建一个会话对象。对于频繁使用的系统,这可能是一个问题(性能)。

票数 109
EN

Stack Overflow用户

发布于 2010-01-12 21:55:11

要回答最初的问题“如何正确地将routedata传递给错误控制器?”:

代码语言:javascript
复制
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));

然后在您的ErrorController类中,实现如下函数:

代码语言:javascript
复制
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult Error(Exception exception)
{
    return View("Error", exception);
}

这会将异常推送到视图中。视图页应声明如下:

代码语言:javascript
复制
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<System.Exception>" %>

以及显示错误的代码:

代码语言:javascript
复制
<% if(Model != null) { %>  <p><b>Detailed error:</b><br />  <span class="error"><%= Helpers.General.GetErrorMessage((Exception)Model, false) %></span></p> <% } %>

下面是从异常树中收集所有异常消息的函数:

代码语言:javascript
复制
    public static string GetErrorMessage(Exception ex, bool includeStackTrace)
    {
        StringBuilder msg = new StringBuilder();
        BuildErrorMessage(ex, ref msg);
        if (includeStackTrace)
        {
            msg.Append("\n");
            msg.Append(ex.StackTrace);
        }
        return msg.ToString();
    }

    private static void BuildErrorMessage(Exception ex, ref StringBuilder msg)
    {
        if (ex != null)
        {
            msg.Append(ex.Message);
            msg.Append("\n");
            if (ex.InnerException != null)
            {
                BuildErrorMessage(ex.InnerException, ref msg);
            }
        }
    }
票数 30
EN

Stack Overflow用户

发布于 2011-05-10 23:45:39

我找到了Lion_cl提到的ajax问题的解决方案。

global.asax:

代码语言:javascript
复制
protected void Application_Error()
    {           
        if (HttpContext.Current.Request.IsAjaxRequest())
        {
            HttpContext ctx = HttpContext.Current;
            ctx.Response.Clear();
            RequestContext rc = ((MvcHandler)ctx.CurrentHandler).RequestContext;
            rc.RouteData.Values["action"] = "AjaxGlobalError";

            // TODO: distinguish between 404 and other errors if needed
            rc.RouteData.Values["newActionName"] = "WrongRequest";

            rc.RouteData.Values["controller"] = "ErrorPages";
            IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
            IController controller = factory.CreateController(rc, "ErrorPages");
            controller.Execute(rc);
            ctx.Server.ClearError();
        }
    }

ErrorPagesController

代码语言:javascript
复制
public ActionResult AjaxGlobalError(string newActionName)
    {
        return new AjaxRedirectResult(Url.Action(newActionName), this.ControllerContext);
    }

AjaxRedirectResult

代码语言:javascript
复制
public class AjaxRedirectResult : RedirectResult
{
    public AjaxRedirectResult(string url, ControllerContext controllerContext)
        : base(url)
    {
        ExecuteResult(controllerContext);
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            JavaScriptResult result = new JavaScriptResult()
            {
                Script = "try{history.pushState(null,null,window.location.href);}catch(err){}window.location.replace('" + UrlHelper.GenerateContentUrl(this.Url, context.HttpContext) + "');"
            };

            result.ExecuteResult(context);
        }
        else
        {
            base.ExecuteResult(context);
        }
    }
}

AjaxRequestExtension

代码语言:javascript
复制
public static class AjaxRequestExtension
{
    public static bool IsAjaxRequest(this HttpRequest request)
    {
        return (request.Headers["X-Requested-With"] != null && request.Headers["X-Requested-With"] == "XMLHttpRequest");
    }
}
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1171035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档