Asp.net mvc 4 混合MVC和WebAPI错误处理
我们有一个Asp.net mvc 4 混合MVC和WebAPI错误处理,asp.net-mvc-4,asp.net-web-api,error-handling,Asp.net Mvc 4,Asp.net Web Api,Error Handling,我们有一个mvc4web应用程序,其中我们使用web.config文件来处理自定义错误 <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="403" />
mvc4
web应用程序,其中我们使用web.config
文件来处理自定义错误
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="403" />
<error statusCode="403" responseMode="ExecuteURL" path="/Error/AccessDenied" />
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
<remove statusCode="500" />
<error statusCode="500" responseMode="ExecuteURL" path="/Error/ApplicationError" />
</httpErrors>
</system.webServer>
我们面临的问题(我想!)是,最初的MVC
错误处理是拦截BadRequest
结果(这是合理的),因此HttpResponseMessage
结果数据永远不会返回到调用的AngularJS
方法
在这种混合(MVC/Web-API
)环境中处理错误的最佳方法是什么,这样Web-API
HttpResponseMessages
就不会丢失
谢谢。我不确定是否找到了最好的解决方案,但最后我从Web.config中删除了httpErrors部分,并在Global.asax中构建了自己的错误处理程序,并提供了以下帖子的帮助:
public void Application_Error(Object sender, EventArgs e)
{
var httpContext = ((MvcApplication) sender).Context;
var currentController = "";
var currentAction = "";
var currentRouteData =
RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
if (currentRouteData != null)
{
if (
!String.IsNullOrEmpty(
currentRouteData.Values["controller"]?.ToString()))
{
currentController = currentRouteData.Values["controller"].ToString();
}
if (!String.IsNullOrEmpty(currentRouteData.Values["action"]?.ToString()))
{
currentAction = currentRouteData.Values["action"].ToString();
}
}
var ex = Server.GetLastError();
var httpEx = ex as HttpException;
var controller = new ErrorController();
var routeData = new RouteData();
var statusCode = httpEx?.GetHttpCode() ?? 500;
string action;
switch (statusCode)
{
case 400:
action = "BadRequest";
break;
case 403:
action = "AccessDenied";
break;
case 404:
action = "NotFound";
break;
default:
action = "Index";
break;
}
httpContext.ClearError();
httpContext.Response.Clear();
httpContext.Response.StatusCode = statusCode;
httpContext.Response.TrySkipIisCustomErrors = true;
if (statusCode >= 500)
{
Server.Transfer("/Error/ServerError.html");
return;
}
routeData.Values["controller"] = "Error";
routeData.Values["action"] = action;
routeData.Values["statusCode"] = statusCode;
controller.ViewData.Model = new HandleErrorInfo(ex, currentController,
currentAction);
((IController) controller).Execute(
new RequestContext(new HttpContextWrapper(httpContext), routeData));
}
我的错误控制器如下所示:
[AllowAnonymous]
public sealed class ErrorController
: AblController
{
public ActionResult Index(int statusCode)
{
ViewBag.StatusCode = statusCode;
return View("Error");
}
// HTTP 400 - Bad Request
public ActionResult BadRequest()
{
// Now handled by Global.asax - Application_Error
// Response.StatusCode = (int) HttpStatusCode.BadRequest;
// Response.TrySkipIisCustomErrors = true;
if (Request.IsAjaxRequest())
{
return Json(
new
{
error = new ErrorSummary("Bad Request")
});
}
return View();
}
// HTTP 403 - Access Denied
public ActionResult AccessDenied()
{
// Now handled by Global.asax - Application_Error
// Response.StatusCode = (int) HttpStatusCode.Forbidden;
// Response.TrySkipIisCustomErrors = true;
if (Request.IsAjaxRequest())
{
return Json(
new
{
error = new ErrorSummary("Access Denied")
});
}
return View();
}
// HTTP 404 - Not Found
public ActionResult NotFound()
{
// Now handled by Global.asax - Application_Error
// Response.StatusCode = (int) HttpStatusCode.NotFound;
// Response.TrySkipIisCustomErrors = true;
if (Request.IsAjaxRequest())
{
return Json(
new
{
error = new ErrorSummary("Not Found")
});
}
return View();
}
}
}
我还在Web.config中关闭了自定义错误模式
<customErrors mode="Off" />
此解决方案需要更多的测试,但到目前为止,它的性能似乎符合预期/要求
<customErrors mode="Off" />