提问人:Alex Muha 提问时间:1/30/2021 更新时间:2/2/2021 访问量:1388
ASP.NET MVC 5 如何将错误消息传递给 ajax 请求的结果
ASP.NET MVC 5 How to pass an error message to the result of an ajax request
问:
在 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
答:
我也没有任何问题,因为我从未收到过 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();
}
评论
HttpConext.Session
HttpContext.Items
您也可以通过以下方式使用:
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);
}
});
评论
有几种方法可以管理错误。
- 使用 FilterAttribute 管理 Ajax 操作或请求中发生的错误。
- 在 Web 配置中管理服务器端错误,例如,如果找不到页面,则重定向到 ErrorPage404 和其他错误.............
- 从发生错误的操作中,将信息放在 ViewBag 或 TempData 中,将其重定向到错误管理操作,或者使用操作输入参数执行此操作。
我给你的建议
对所有 http 操作和请求使用 filter属性,并将所有错误传递给单个操作。我在这篇文章中举了一个例子。
对于服务器端错误,请使用 Web 配置并将所有错误仅传输到一个操作,然后使用错误代码向用户显示相应的文本。我在这篇文章中举了一个例子。
对于 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 }
);
评论