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文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
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如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
/// <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“的那两行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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中添加:
1 |
c.OperationFilter<HttpHeaderFilter>();
|
大功告成,如下图:
标签:webapi,c#,Filter,context,cs,new,actionContext,swagger,public From: https://www.cnblogs.com/DoNetCShap/p/17823650.html