ASP.NET MVC 5 如何将错误消息传递给 ajax 请求的结果

ASP.NET MVC 5 How to pass an error message to the result of an ajax request

提问人:Alex Muha 提问时间:1/30/2021 更新时间:2/2/2021 访问量:1388

问:

在 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) 以某种方式将我需要的消息传递给模块调用的控制器代码?
httpErrorshttpErrors

C# AJAX ASP.NET-MVC 错误处理

评论

0赞 Meysam Asadi 1/30/2021
请参阅以下两个链接:c-sharpcorner.com/UploadFile/97fc7a/... 和 stackoverflow.com/questions/4707755/...

答:

0赞 Meysam Asadi 1/30/2021 #1

我也没有任何问题,因为我从未收到过 Ajax 的页面错误,但据我所知,在这种情况下无法管理浏览器错误。我将在下面举个例子,并在最后为您放置一个链接。

public class JsonData
{
    public string HtmlMsg { get; set; }
    public string HtmlBody { get; set; }
    public bool Success { get; set; }
}

控制器

[HttpPost]
public ActionResult AddToBasket(string basket)
{
    //operations ......
    if(Success)
      return Json(new JsonData()
      {
        HtmlMsg = "success operation",
        HtmlBody = "",
        Success = true,
      });
    else
      return Json(new JsonData()
      {
          HtmlMsg = "failed operation",
          HtmlBody = "",
         Success = false,
      });
}

AJAX 代码

$.ajax({
    url: "/Basket/AddToBasket",
    data: { basket: basket },
    type: "Post",
    dataType: "Json",
    success: function (result) {
       if(result.Success)
           //success work....
       esle
           //failed work.........
    },
    error: function () {
        closeshowLoad();
    }
});

请参阅此链接:防止未处理的 jQuery AJAX 错误

以消息 400 为例。在浏览 OtherError 页上的相应操作时,可以将错误文本保存在 TempData 或 ViewBag 中。并将其显示在 OtherError 页面上。

public ActionResult ErrorPage()
{
   ViewBag.ErrorText = ViewBag.SenderActionErrorText;
   return View();
}

评论

0赞 Alex Muha 1/30/2021
谢谢,我有这个想法,我会尝试使用这个方案
0赞 Alex Muha 1/30/2021
这个想法很清楚,但我不喜欢它,因为在客户端代码级别使用了“拐杖”,因此在支持项目时很容易忘记它。我想在客户端代码中保留正常的实现,以处理“正确”的错误代码
0赞 Alex Muha 2/2/2021
>在我尝试过的 OtherError 页面上导航相应操作时,您可以将错误文本保存在 TempData 或 ViewBag 中,TempData 和 ViewBag 都不会传递给这些控制器,这些控制器由 HttpErrors 触发:-(通过 httpContext,也无法通过 或HttpConext.SessionHttpContext.Items
0赞 Meysam Asadi 2/2/2021
如果无法使用 viewbag 或 TempData,则可以使用 HttpContext,例如 HttpContext.Current.Session: [“CapchaStringlogin”] = randomString
0赞 Meysam Asadi 2/2/2021
当然,在这种情况下,最好使用 httpContext。因为它记录了具有相同请求的信息。
0赞 Meysam Asadi 1/31/2021 #2

您也可以通过以下方式使用:

HandlerAttribute (处理程序属性)

    public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            filterContext.ExceptionHandled = true;
            filterContext.Result = new JsonResult
            {
                Data = new {
                    success = false, 
                    error = filterContext.Exception.Message.ToString(),
                    ExceptionStackTrack = filterContext.Exception.StackTrace,
                    ControllerName = filterContext.RouteData.Values["controller"].ToString(),
                    ActionName = filterContext.RouteData.Values["action"].ToString(),
                    ExceptionLogTime = DateTime.Now
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
    }

测试操作

[HttpPost]
public ActionResult Foo(string basket)
{
   if (string.IsNullOrEmpty(basket))
   {
       throw new Exception("your text");
   }
   return Json(new { success = true });
}

register 处理程序属性

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

AJAX 请求

$.ajax({
      url: "/Pages/Foo",
      data: { basket: null },
       type: "Post",
       dataType: "Json",
       success: function (result) {
                if (!result.success) {
                          alert(result.error);
                          alert(result.ExceptionStackTrack);
                          alert(result.ExceptionLogTime);
                          alert(result.ActionName);
                 } else {
                         //successfull         
                 }
       },
       error: function (XMLHttpRequest, textStatus, errorThrown) {
                 alert(XMLHttpRequest.status);
       }
});
     

评论

0赞 Alex Muha 2/1/2021
这个解决方案是可以理解的,但我不喜欢它。我想在客户端上收到一条消息,其中包含正确的错误代码(我从服务器 API 收到的代码)
0赞 Meysam Asadi 2/1/2021
好吧,它还修复了服务器 api 错误。使用此配置,您可以管理服务器错误
0赞 Meysam Asadi 2/2/2021 #3

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

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

我给你的建议

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

  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());

    }      
}

register 处理程序属性

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 }
);

服务器错误示例:enter image description here

示例操作错误 filter属性:enter image description here

评论

0赞 Alex Muha 2/2/2021
非常感谢您坚持不懈地帮助我。但我想在客户端上收到正确的错误代码。但你所有的选择都不允许你这样做