zoukankan      html  css  js  c++  java
  • 一、WebAPI自定义过滤器的使用

    一、WebAPI自定义过滤器的使用

    1、注册过滤器

    using System.Web.Http;
    using KYINT.WebAPIService.Handler;
    
    namespace KYINT.WebAPIService
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                // Web API 配置和服务
    
                // Web API 路由
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                     name: "ActionApi",
                     routeTemplate: "{controller}/{action}/{id}",
                     defaults: new { id = RouteParameter.Optional }
                 );
    
                //移除XML格式,采用Json进行数据交互
                config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
    
                //处理DateTime类型序列化后含有T的问题
                config.Formatters.JsonFormatter.SerializerSettings.Converters.Insert(0, new JsonDateTimeConverter());
    
                //添加全局异常处理器
                config.Filters.Add(new KYExceptionFilter());
    
                //添加全局认证过滤器
                config.Filters.Add(new KYAuthenticationFilter());
    
                //添加全局统计过滤器
                config.Filters.Add(new StatisticsFilter());
            }
        }
    }

    2、全局认证过滤器

        /// <summary>
        /// 认证过滤器,验证是否含有UUID标头
        /// </summary>
        public class KYAuthenticationFilter : Attribute, IAuthenticationFilter
        {
            public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
            {
                if (KYAuthenticationFilter.SkipAuthentication(context))
                {
                    return ;
                }
    
                IPrincipal principal = await this.AuthenticateAsync(context.Request);
                if (principal == null)
                {
                    context.ErrorResult = new AuthenticationFailureResult("未授权请求", context.Request);
                }
                else
                {
                    context.Principal = principal;
                }
            }

    /// <summary> /// 从授权表头中取出授权值并验证,验证通过构建正确的Principal对象 /// </summary> /// <param name="request"></param> /// <returns></returns> private Task<IPrincipal> AuthenticateAsync(HttpRequestMessage request) { return Task.Run<IPrincipal>(() => { string UUID = request.GetHeader("UUID"); if (string.IsNullOrWhiteSpace(UUID)) { return null; } User user = TB_NUsersBLL.GetUser(UUID); if (user == null) { return null; } request.Properties.Add("UUID", user); IEnumerable<Claim> claims = new List<Claim>() { new Claim(ClaimTypes.Sid, UUID), new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.MobilePhone, user.TelePhone) }; return new ClaimsPrincipal(new ClaimsIdentity(claims)); }); } /// <summary> /// 检查控制器或方法是否启用NoAuthenticationAttribute,如果启用了,则跳过认证 /// </summary> /// <param name="context"></param> /// <returns></returns> private static bool SkipAuthentication(HttpAuthenticationContext context) { return context.ActionContext.ActionDescriptor.GetCustomAttributes<NoAuthenticationAttribute>().Any<NoAuthenticationAttribute>() || context.ActionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<NoAuthenticationAttribute>().Any<NoAuthenticationAttribute>(); } }

    2.1、不需鉴权过滤器

     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
        public sealed class NoAuthenticationAttribute : Attribute
        {
        }

    3、全局统计过滤器

        /// <summary>
        /// 全局统计过滤器
        /// </summary>
        public class StatisticsFilter : ActionFilterAttribute
        {
            public override void OnActionExecuting(HttpActionContext actionContext)
            {
                base.OnActionExecuting(actionContext);
                //以下为业务处理
                string methodName = actionContext.Request.RequestUri.AbsolutePath;
                //异步调用
                Task.Factory.StartNew((obj) => TA_InteriorAppModuleInfoBLL.AddModuleInfo((string)obj), methodName);
            }
        }

     4、全局异常过滤器

        /// <summary>
        /// 全局异常过滤器
        /// </summary>
        public class KYExceptionFilter : ExceptionFilterAttribute
        {
            public override void OnException(HttpActionExecutedContext actionExecutedContext)
            {
                #region 标准做法
    
                //var exception = actionExecutedContext.Exception;
    
                //if (exception is BusinessException)     //业务异常,一般不需记录日志,直接反馈错误信息至前端
                //{
                //    actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse((HttpStatusCode)exception.HResult, new HttpError(exception.Message));
                //}
                //else        //未处理异常如数据库访问出错、代码层面异常等,返回错误信息并记录日志
                //{
                //    actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, new HttpError(exception.Message));
                //    //LogHelper.Error(typeof(KYExceptionFilter), exception);
                //    LogHelper.Error(actionExecutedContext.Request.RequestUri.AbsolutePath, exception);
                //}
    
                #endregion
    
                #region 变异做法(受限于现在接口及各终端通行做法,后期需要调整为标准做法)
    
                var exception = actionExecutedContext.Exception;
    
                if (exception is BusinessException)     //业务异常,一般不需记录日志,直接反馈错误信息至前端
                {
                    actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.OK, Utils.AssembleMsg(exception.Message));
                }
                else if (exception is OperationCanceledException)//ThirdParty/GetMobilePlace 处理已取消该操作异常
                {
                    actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.OK, Utils.AssembleMsg("客户端取消了这次请求"));
                }
                else        //未处理异常如数据库访问出错、代码层面异常等,返回错误信息并记录日志
                {
                    actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.OK, Utils.AssembleMsg("服务器处理出错"));
                    LogHelper.Error(typeof(KYExceptionFilter), actionExecutedContext.Request.RequestUri.AbsolutePath, exception);
                }
    
                #endregion
            }
        }
  • 相关阅读:
    微信成为开发者C#代码
    Ajax.ActionLink()方法的使用
    Entity FrameWork初始化数据库的四种策略
    最长公共子序列
    表达式求值
    韩信点兵
    蛇形填数
    5个数求最值
    求转置矩阵问题
    素数求和问题
  • 原文地址:https://www.cnblogs.com/woadmin/p/9407074.html
Copyright © 2011-2022 走看看