混合使用MVC和Web API错误处理

尼尔

我们有一个MVC 4Web应用程序,使用该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>

所有这些都按预期工作。

现在,我们开始使用AngularJS和来在该项目中实现一些新功能Web APIWeb API控制器操作中,我们始终返回HttpResponseMessage来指示调用成功/失败。例如:

return Request.CreateResponse(HttpStatusCode.BadRequest, result);

我们遇到的问题(我认为!)是,最初的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" />

该解决方案需要更多测试,但到目前为止,它似乎正在按预期/要求执行。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C检查NULL和错误处理

来自分类Dev

EJB,XA事务和错误处理

来自分类Dev

如何在整个api调用中使用node.js中的全局错误处理代码

来自分类Dev

使用JavaCompiler API进行Java代码编译和编译错误处理

来自分类Dev

如何使用Bluebird错误处理程序?

来自分类Dev

fgets和错误处理的小麻烦

来自分类Dev

Scala:错误处理和异常匹配

来自分类Dev

Go方法链接和错误处理

来自分类Dev

基于RESTful API的系统的体系结构决策和错误处理(使用Nginx + Redis)

来自分类Dev

错误处理和信号

来自分类Dev

Spring MVC的Freemarker模板错误处理

来自分类Dev

bash:错误处理和功能

来自分类Dev

jQuery延迟的错误处理和恢复

来自分类Dev

Swift 2.2错误处理和音频

来自分类Dev

拒绝Javascript承诺和错误处理

来自分类Dev

Web API错误处理返回json

来自分类Dev

python asyncio和错误处理

来自分类Dev

跨域错误处理和WCF

来自分类Dev

如何在整个api调用中使用node.js中的全局错误处理代码

来自分类Dev

Python错误处理和连接错误

来自分类Dev

Web表单中的错误处理

来自分类Dev

ASP .Net MVC中的错误处理

来自分类Dev

expressJS承诺和错误处理

来自分类Dev

Powershell 警告和错误处理

来自分类Dev

JsonResult 和 ActionResult 的错误处理

来自分类Dev

Javascript:图像错误处理和嵌套

来自分类Dev

Vba 错误处理和类 (Excel)

来自分类Dev

Swift 闭包和错误处理

来自分类Dev

使用 dask 发送并行 API 请求和错误处理