WebApi全局异常处理方式

Posted keepsilence

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebApi全局异常处理方式相关的知识,希望对你有一定的参考价值。

自定义错误消息

 public class ErrorMessage:DelegatingHandler
    {
  
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>((responseToCompleteTask) =>
            {
                HttpResponseMessage response = responseToCompleteTask.Result;
                HttpError error = null;
                if (response.TryGetContentValue<HttpError>(out error))
                {
                    //自定义错误处理  
                    //error.Message = "这个接口调用出错了";  
                }
                if (error != null)
                {   //这是本人创建的一个返回类                   
                    var resultMsg = new BaseResModel<BaseModel> { errorno = (int)response.StatusCode, page = -1, total = -1, records = -1 };
                    return new HttpResponseMessage
                    {
                        Content = new StringContent(SerializeUtils<BaseResModel<BaseModel>>.Serialize(resultMsg),
                        System.Text.Encoding.GetEncoding("UTF-8"), "application/json"),
                        StatusCode = HttpStatusCode.OK
                    };
                }
                else
                {
                    return response;
                }
            });
        }
    }

全局异常处理包括404

public class NotFoundActionSelector: ApiControllerActionSelector
    {
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            HttpActionDescriptor decriptor = null;
            try
            {
                decriptor = base.SelectAction(controllerContext);
            }
            catch (HttpResponseException ex)
            {
                var code = ex.Response.StatusCode;
                if (code != HttpStatusCode.NotFound && code != HttpStatusCode.MethodNotAllowed)
                    throw;
                var routeData = controllerContext.RouteData;
                routeData.Values["action"] = "Handle404";
                IHttpController httpController = new ErrorController();
                controllerContext.Controller = httpController;
                controllerContext.ControllerDescriptor = new HttpControllerDescriptor(controllerContext.Configuration, "Error", httpController.GetType());
                decriptor = base.SelectAction(controllerContext);
            }
            return decriptor;
        }
    }

  

public class NotFoundControllerSelector : DefaultHttpControllerSelector
    {
        public NotFoundControllerSelector(HttpConfiguration configuration)
            : base(configuration)
        {
        }

        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            HttpControllerDescriptor decriptor = null;
            try
            {
                decriptor = base.SelectController(request);
            }
            catch (HttpResponseException ex)
            {
                var code = ex.Response.StatusCode;
                if (code != HttpStatusCode.NotFound)
                    throw;
                var routeValues = request.GetRouteData().Values;
                routeValues["controller"] = "Error";
                routeValues["action"] = "Handle404";
                decriptor = base.SelectController(request);
            }
            return decriptor;
        }
    }

权限过滤

public class SupportFilter : AuthorizeAttribute
    {
        //重写基类的验证方式,加入我们自定义的Ticket验证
        RedisHelper redis = new RedisHelper(1);
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            //url获取token
            var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;

            var token = content.Request.QueryString["Token"];
            var userid = content.Request.QueryString["userid"] != null ? int.Parse(content.Request.QueryString["userid"]) : 0;
            var mac = content.Request.QueryString["mac"] != null ? content.Request.QueryString["mac"] : null;
            var routes = new RouteCollection();
            RouteConfig.RegisterRoutes(routes);
            RouteData routeData = routes.GetRouteData(content);
            //取出区域的控制器Action,id
            string controller = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            string action = actionContext.ActionDescriptor.ActionName;
            //URL路径
            string filePath = HttpContext.Current.Request.FilePath;



            if ((controller.ToLower() == "user" && action.ToLower() == "login")
                || (controller.ToLower() == "user" && action.ToLower() == "register" )|| (controller.ToLower() == "banner" && action.ToLower() == "getbanner") || (controller.ToLower() == "device" && action.ToLower() == "login"))
                
            {

            }
            else
            {
                var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                if (isAnonymous) base.OnAuthorization(actionContext);
                if (userid != 0 && token != null && token.Length > 0)
                {
                    if (redis.StringGet("user_token_" + userid.ToString()) != token)
                    {
                        HandleUnauthorizedRequest(actionContext);
                    }
                }
                else if (mac != null && token != null && token.Length > 0)
                {
                    if (redis.StringGet("device_token_" + mac) != token)
                    {
                        HandleUnauthorizedRequest(actionContext);
                    }
                }
                else
                    HandleUnauthorizedRequest(actionContext);

            }
        }
        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            base.HandleUnauthorizedRequest(actionContext);
            if (actionContext.Response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
            {

                actionContext.Response.Content = new StringContent(SerializeUtils<BaseResModel<BaseModel>>.Serialize(new BaseModel() { errorno = -4, errormsg = "" }), System.Text.Encoding.UTF8, "application/json");
            }
        }
    }

  

  

 

 

在webconfig中配置

   config.MessageHandlers.Add(new ErrorMessage());
            config.Filters.Add(new SupportFilter());
            config.Services.Replace(typeof(IHttpControllerSelector), new NotFoundControllerSelector(config));
            config.Services.Replace(typeof(IHttpActionSelector), new NotFoundActionSelector());
            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            config.Routes.MapHttpRoute(
              name: "Error404",
              routeTemplate: "{*url}",
              defaults: new { controller = "Error", action = "Handle404" }
          );

  

以上是关于WebApi全局异常处理方式的主要内容,如果未能解决你的问题,请参考以下文章

全局异常方式处理自定义异常 @RestControllerAdvice + @ExceptionHandler

Spring全局异常处理的三种方式

Spring Boot 2.X:全局异常处理

使用 NLog 在 ASP.NET Web API 2.1 中进行全局异常处理?

.net捕获全局异常并且记录日志多线程方式发送邮件提醒

WEB 项目中的全局异常处理