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中构建了自己的错误处理程序,并提供了以下帖子的帮助:

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" />