ASP.NET MVC - 使ExceptionContext返回正常响应

时间:2016-04-19 10:46:46

标签: asp.net-mvc asp.net-mvc-5

我们正在开发新的MVC5网络应用程序,我们正在使用现有的API库来实现某些功能。

现在,这些API库会抛出某些需要传回客户端浏览器的异常类型。

我希望如何处理这些例外:

  1. 如果被调用的操作返回一个视图,则将用户带到一个带有异常消息的页面
  2. 如果被调用的操作返回JSON字符串,则以字符串格式
  3. 返回响应

    我现在关注的是#2,因为控制器的'OnException'方法总是返回服务器错误,默认情况下ASP.NET将返回默认的自定义错误,除非我按如下方式更改Web应用程序配置

    <system.web> 
    ...
      <customErrors mode="Off"/>
    <system.webServer>
    ...
       <httpErrors errorMode="Detailed" />
    

    我的问题是,如何从“OnException”返回JSON字符串而不必更改上面显示的Web配置? (即,提升ExceptionContext以返回常规JSON响应字符串)。

    TIA

    protected override void OnException(ExceptionContext filterContext)
        {
            //If the exeption is already handled we do nothing
            if (filterContext.ExceptionHandled)
            {
                return;
            }
    
            // Init
            var vm = new ExceptionViewModel();
            Exception ex = filterContext.Exception;
            var controllerName = filterContext.RouteData.Values["controller"].ToString();
            var actionName = filterContext.RouteData.Values["action"].ToString();
    
            // Get action return type
            Type controllerType = filterContext.Controller.GetType();
            var method = controllerType.GetMethod(actionName);
            Type returnType = null;
    
            // If method is null, default to JSONREsult
            if (method == null)
            {
                returnType = typeof(JsonResult);
            }
            else
            {
                returnType = method.ReturnType;
            }
    
            // Log exception
            vm.ErrorLogId = LogException(ex);
    
            // Assign Exception View Model
            if (ex is MyCustomExceptionType)
            {
                filterContext.HttpContext.Response.StatusCode = 200;
                vm.ErrorMessage = filterContext.Exception.Message;
            }
            else if (ex is NotAuthorizedException)
            {
                // Get Http exception
                var httpEx = ex as NotAuthorizedException;
                filterContext.HttpContext.Response.StatusCode = httpEx.GetHttpCode();
                vm.ErrorMessage = httpEx.Message;
            }
            else
            {
                // Set status code to 500 since this exception block indicates an application
                // exception occurred
                filterContext.HttpContext.Response.StatusCode = 500;
                vm.ErrorMessage = "Sorry, I may have malfunctioned. Toink!";
            }
    
            // Prepare data to return back to client
            if (returnType.Equals(typeof(JsonResult)) || returnType.Equals(typeof(Task<JsonResult>)))
            {
                filterContext.Result = new JsonResult()
                {
                    Data = vm.ErrorMessage,
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
            }
            else
            {
                filterContext.Result = new ViewResult()
                {
                    ViewName = "Error",
                    ViewData = new ViewDataDictionary(vm)
                };
            }
    
            // Mark exception as a handled
            filterContext.ExceptionHandled = true;
        }
    

0 个答案:

没有答案