首页 > 解决方案 > ASP.NET MVC 5 如何将错误消息传递给 ajax 请求的结果

问题描述

在 ASP.NET MVC 5 中,我发出一个客户端 (JavaScript) ajax 请求,如果从 API 接收到错误消息,我想将此消息发送到客户端

我在配置文件中使用错误处理:

    <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="400"/>
      <remove statusCode="403"/>
      <remove statusCode="404"/>
      <remove statusCode="500"/>
      <error statusCode="400" path="/SystemPages/OtherError" responseMode="ExecuteURL"/>
      <error statusCode="403" path="/SystemPages/Login" responseMode="Redirect"/>
      <error statusCode="404" path="/SystemPages/NotFoundError" responseMode="ExecuteURL"/>
      <error statusCode="500" path="/SystemPages/InternalServerError" responseMode="ExecuteURL"/>
    </httpErrors>

我在过滤器中有一个错误处理:

 public class ExceptionAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
           ...

在 JavaScript 代码中,如果响应代码与 2XX 不匹配,我将显示错误:

$.ajax({
    type: "POST",
    url: '/api/xxx',
    data: JSON.stringify({ ids: invoiceIds }),
    contentType: "application/json",
    success: function (data) {
        successToast("Success result ....bla bla bla.", "Success");
        window.location.reload(false);
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
        let errorMessage = errorThrown;
        if (XMLHttpRequest.responseText != null && XMLHttpRequest.responseText != '') {
            errorMessage = XMLHttpRequest.responseText;
        }
        errorToast(errorMessage, "Error");
    }
});

问题是这样的:如果我从 API 收到错误(例如,状态码 = 400),我可以在过滤器中处理它,并且我想用相同的错误代码向客户端发送服务器响应,并且响应正文中的错误文本。但在这种情况下(由于错误代码 = 400),模块 httpError 被触发并将其视图插入到响应中。而且我丢失了原始错误描述文本消息。

也许您可以a)在特定情况下
以某种方式停止模块的操作,或者 b)以某种方式将我需要的消息传递给模块调用的控制器代码?httpErrors
httpErrors

标签: c#ajaxasp.net-mvcerror-handling

解决方案


有几种方法可以管理错误。

  1. 使用 FilterAttribute 管理 Ajax 操作或请求中发生的错误。
  2. 管理 web config 中的服务器端错误,例如,如果找不到页面,则重定向到 ErrorPage404 和其他错误............
  3. 从发生错误的操作中,将信息放入 ViewBag 或 TempData 将其重定向到错误管理操作,或者使用操作输入参数进行操作。

我给你的建议

  1. 对所有 http 操作和请求使用过滤器属性,并将所有错误传递给单个操作。我在这篇文章中给出了一个例子。

  2. 对于服务器端错误,使用 web 配置并将所有错误转移到一个操作中,然后使用错误代码向用户显示适当的文本。我在这篇文章中给出了一个例子。

  3. 对于 Ajax 和 jQuery 请求,请使用我之前给出的两个帖子的示例。

这完全取决于程序员在如何管理错误方面的品味。

public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;
        filterContext.Result = new RedirectResult("/Pages/Error?ControllerName=" +
        filterContext.RouteData.Values["controller"].ToString() +
                "&ActionName=" + filterContext.RouteData.Values["action"].ToString() +
                "&Error=" + filterContext.Exception.Message.ToString());

    }      
}

注册 Handler 属性

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
   filters.Add(new MyErrorHandlerAttribute());
}

和 ActionResult

//error 404 & 500 & .............. 
public ActionResult ErrorPage(string errorCode)
{ 
   switch(errorCode)
        {
            case "404":
                ViewBag.Text = "404 Error";
                break;
            case "500":
                ViewBag.Text = "500 Error";
                break;
            case "unknown":
                ViewBag.Text = "unknown Error";
                break;
            default:
                ViewBag.Text = "404 Not Found";
                break;
        }
        return View();
}
//error in  all actions 
public ActionResult Error(string ControllerName, string ActionName, string Error)
{
    ViewBag.Text = "controller: " + ControllerName + "<br /><br />action: " + ActionName + "<br /><br />error message: " + Error;
    return View();
}

和 web.config 用于服务器端错误

 <customErrors mode="On" defaultRedirect="/Pages/ErrorPage?errorCode=unknown">
  <error statusCode="404" redirect="/Pages/ErrorPage?errorCode=404" />
  <error statusCode="500" redirect="/Pages/ErrorPage?errorCode=500" />
</customErrors>

和 routeConfig.cs

//this code add end route
//Add this code to handle non-existing urls
routes.MapRoute(
       name: "404-PageNotFound",
       // This will handle any non-existing urls
       url: "{*url}",
       // "Shared" is the name of your error controller, and "Error" is the action/page
       // that handles all your custom errors
       defaults: new { controller = "Pages", action = "ErrorPage", id = UrlParameter.Optional }
);

示例服务器错误: 在此处输入图像描述

示例动作错误过滤器属性: 在此处输入图像描述


推荐阅读