gpt4 book ai didi

javascript - 与$ ajax一起使用的Asp.Net显示默认错误页面

转载 作者:行者123 更新时间:2023-12-03 08:46:31 25 4
gpt4 key购买 nike

我有一个混合ASP.NET Web窗体/MVC应用程序。当发生500错误时,我要执行以下操作:

如果错误是在Web表单上发生的,

  • 将显示一个自定义* .aspx页面。
  • 如果在返回 View 的 Controller 操作中发生错误,
  • 将显示自定义mvc View 。
  • 如果在响应$ ajax请求的 Controller 操作中发生错误,
  • 显示用javascript构造的自定义消息。 这是我遇到问题的第3个项目。

  • 在所有情况下,我只想记录一次错误。我在global.asax Application_OnError事件过程中记录了Web表单错误。对于我的mvc Controller ,我已将此调用添加到Application_Start事件过程中:
    GlobalFilters.Filters.Add(new HandleErrorAttribute());

    然后创建一个基类,应用程序中的所有 Controller 都派生自该基类。在此基类中,我在OnException事件过程中记录错误。错误记录工作正常。

    对于项目1,自定义* .aspx页面,我将其添加到了web.config,它成功地将所有Webforms错误重定向到我的自定义错误页面:
    <customErrors mode="On" defaultRedirect="MyFolder/MyDefaultErrorPage.aspx" 

    对于项目2,自定义mvc View ,我发现我需要在我的web.config的httpErrors元素中捕获IIS错误。这成功地将所有 Controller 错误重定向到我的自定义错误 View :
        <httpErrors errorMode="Custom" existingResponse="Replace">
    <clear />
    <error statusCode="500" path="/MyFolder/MyErrorView" responseMode="Redirect"/>
    </httpErrors>

    上面的所有方法都工作正常,但是不幸的是,第2项拦截了IIS 500错误,导致所有$ ajax调用都返回到success:事件处理程序,而不是error:事件处理程序,即使 Controller Action 引发异常也是如此。例如,我将此调用从javascript调用为 Controller 操作:
    $.ajax({
    type: "GET",
    url: '/MyFolder/MyControllerAction',
    success: function (data) {
    do_something(data);
    },
    error: function (XMLHttpRequest, ajaxOptions, ex) {
    show_error_message(XMLHttpRequest, ex);
    }

    问题是,当MyControllerAction引发异常时,将调用“成功:”事件处理程序,而不是“错误:”事件处理程序。如果我从web.config中删除拦截IIS 500错误的节点,则会在$ ajax调用中击中所需的“错误:”事件处理程序,但它将显示默认的IIS 500错误页面,而不是我的自定义错误页面。

    有什么方法可以显示我所有Controller错误的自定义错误页面,但仍然有错误:当我从JavaScript进行$ ajax调用时,事件处理程序将触发?

    更新:如果我创建一个从HandleErrorAttribute派生的自定义类,并在GlobalFilters.Filters.Add()中使用它,我将一路走到那里。这会在我的javascript $ ajax调用中触发“错误:”事件。问题是XMLHttpRequest.responseText不包含我的自定义消息(它只是说“由于发生内部服务器错误而无法显示该页面。”)。是否有任何方法可以将自定义消息传递给XMLHttpRequest.responseText,该消息将返回到$ .ajax调用?
    public class MyCustomHandleErrorAttribute : HandleErrorAttribute
    {
    public override void OnException(ExceptionContext filterContext)
    {
    if(filterContext.HttpContext.Request.IsAjaxRequest()
    && filterContext.Exception != null)
    {
    //500 is needed so that $ajax "error:" event handler is hit, instead of "success:"
    filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

    filterContext.Result = new JsonResult
    {
    JsonRequestBehavior = JsonRequestBehavior.AllowGet,
    Data = new
    {
    Message = "Custom message will go here"
    }
    };

    //this stops Application_OnError from firing
    filterContext.ExceptionHandled = true;
    }
    else
    {
    filterContext.Result = new ContentResult()
    {
    Content = "<html><body>Custom message will go here</body></html>",
    ContentType = "text/html"
    };
    filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
    filterContext.ExceptionHandled = true;
    }
    }

    最佳答案

    综上所述:当服务器上发生运行时错误时,我希望能够将自定义错误消息传递给$ ajax事件处理程序(我不需要默认的IIS错误消息),而我希望获得$ ajax触发“错误:”功能(而不是“成功:”功能)。

    上面的问题中概述的自定义HandleErrorAttribute可以工作,但是还需要进行两项更改才能覆盖默认的IIS错误消息:

  • 将此行添加到自定义属性的OnException过程中的第一个“if”块(处理ajax错误的“if”块):

    filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
  • 将此添加到web.config中的httpErrors标记中:

    errorMode =“自定义” existingResponse =“PassThrough”

  • existingResponse的值也可以是“自动”

    我的最终自定义属性如下所示:
    public class MyCustomHandleErrorAttribute : HandleErrorAttribute
    {
    public override void OnException(ExceptionContext filterContext)
    {
    //log the error
    if (filterContext.Exception != null)
    {
    //note that Application_Error makes the same call for errors it handles.
    //this method and Application_Error are the only two places in the application where errors are handled.
    MyErrorLogger(filterContext.Exception.GetBaseException());
    }

    if (filterContext.HttpContext.Request.IsAjaxRequest()
    && filterContext.Exception != null)
    {
    //this is an error from a $ajax call.
    //500 is needed so that $ajax "error:" function is hit, instead of "success:"
    filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

    filterContext.Result = new JsonResult()
    {
    Data = new
    {
    MyCustomMessage="A custom error message",
    IsException = true
    }
    };

    //this stops Application_OnError from firing
    filterContext.ExceptionHandled = true;

    //this stops the web site from using the default IIS 500 error.
    //in addition must set existingResponse="PassThrough" or "Auto" in web.config httpErrors element.
    filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }
    else
    {
    //this is an error in a controller method that returns a view
    filterContext.Result = new RedirectToRouteResult(
    new System.Web.Routing.RouteValueDictionary
    {
    {"action", "Error500" },
    {"controller", "Error" },
    { "Message", "My custom message here."}
    });
    filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
    filterContext.ExceptionHandled = true;
    }
    }
    }

    上面创建的自定义错误消息在“error:”函数的“XMLHttpRequest.responseText”参数中作为JSON对象被客户端解析:
    error: function (XMLHttpRequest, ajaxOptions, ex) {
    alert(jQuery.parseJSON(XMLHttpRequest.responseText).MyCustomMessage);
    }

    关于javascript - 与$ ajax一起使用的Asp.Net显示默认错误页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52761536/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com