c# webapi 在swagger里添加全局過濾器


Swagger原理

  Swagger就是利用反射技術遍歷所有Api接口,並且從xml文件中讀取注釋,在利用Swagger內置的模板組合html顯示至客戶端實現接口可視化,並且可調用。

在WEB Api中,引入了面向切面編程(AOP)的思想,在某些特定的位置可以插入特定的Filter進行過程攔截處理。引入了這一機制可以更好地踐行DRY(Don’t Repeat Yourself)思想,通過Filter能統一地對一些通用邏輯進行處理,如:權限校驗、參數加解密、參數校驗等方面我們都可以利用這一特性進行統一處理,今天我們來介紹Filter的開發、使用以及討論他們的執行順序。

Filter的開發和調用

在默認的WebApi中,框架提供了三種Filter,他們的功能和運行條件如下表所示:

Filter 類型 實現的接口 描述
Authorization IAuthorizationFilter 最先運行的Filter,被用作請求權限校驗
Action IActionFilter 在Action運行的前、后運行
Exception IExceptionFilter 當異常發生的時候運行

添加注冊全局Filter的方法

1.創建一個ApiAuthorizationFilterAttribute.cs和ApiExceptionFilterAttribute.cs兩個文件:

ApiAuthorizationFilterAttribute.cs文件如下:

    public class ApiAuthorizationFilterAttribute : AuthorizationFilterAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {

            //如果用戶方位的Action帶有AllowAnonymousAttribute,則不進行授權驗證
            if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
            {
                return;
            }

            var authorization = actionContext.Request.Headers.Authorization;

            if (authorization == null || authorization.Scheme != "Bearer")
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new { status = "failed", message = "token不正確!!!" });
            }
            else
            {
                string username;

                var token = authorization.Parameter;
          //以下就是驗證token的方法,可以自己寫方法進行驗證啦
                if (!ValidateToken(token, out username))
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new { status = "failed", message = "token不正確!!!" });
                }
            }
        }
    }

  ApiExceptionFilterAttribute.cs如下:

    /// <summary>
    /// 捕捉異常
    /// </summary>
    public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
    {
        /// <summary>
        /// 重寫基類的異常處理方法
        /// </summary>
        /// <param name="context"></param>
        public override void OnException(HttpActionExecutedContext context)
        {
            //context.Exception.StackTrace
            //1.異常日志記錄
            LogHelper.Error(context.Exception.ToString());

            //2.返回調用方具體的異常信息
            if (context.Exception is NotImplementedException)
            {
                context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
            }
            else if (context.Exception is TimeoutException)
            {
                context.Response = new HttpResponseMessage(HttpStatusCode.RequestTimeout);
            }
            else
            {
                //這里可以根據項目需要返回到客戶端特定的狀態碼。如果找不到相應的異常,統一返回服務端錯誤500
                context.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }

            base.OnException(context);

        }

        private JsonMediaTypeFormatter _JsonFormatter;
        private JsonMediaTypeFormatter JsonFormatter
        {
            get
            {
                if (_JsonFormatter == null)
                {
                    _JsonFormatter = new JsonMediaTypeFormatter();
                    _JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                }
                return _JsonFormatter;
            }
        }
    }

2.在WebApiConfig.cs文件中添加”注冊全局Filter“的那兩行

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服務

            // Web API 路由
            config.MapHttpAttributeRoutes();

            //注冊全局Filter
            config.Filters.Add(new ApiAuthorizationFilterAttribute());
            config.Filters.Add(new ApiExceptionFilterAttribute());

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

            log4net.Config.XmlConfigurator.Configure();

        }
    }

3.進行swagger的相關配置,新建一個HttpHeaderFilter.cs文件:

    public class HttpHeaderFilter : IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            if (operation.parameters == null)
            {
                operation.parameters = new List<Parameter>();
            }

            var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline(); //判斷是否添加權限過濾器
            var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Instance).Any(filter => filter is ApiAuthorizationFilterAttribute); //判斷是否需要經過驗證 
            var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();//判斷是否否允許匿名方法
            if (isAuthorized && !allowAnonymous)
            {
                operation.parameters.Add(new Parameter { name = "Authorization", @in = "header", description = "Token", required = false, type = "string" });
            }
        }
    }

4.在文件SwaggerConfig.cs文件中找到Register方法,GlobalConfiguration.Configuration.EnableSwagger中添加:

c.OperationFilter<HttpHeaderFilter>();

  大功告成,如下圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM