概述
前言
最近公司有个WebApi接口打算用.net core重构下,由于业务需求,要求对传输过程中所有数据进行DES加密,之前的接口是在每个Action中进行加解密操作,这个场景很容易想到.net core中的ActionFilter过滤器,可以非常完美的解决这一问题,于是进行了改造。
运行环境
运行环境:.Net 5
开发环境:VS2019 16.8.2
ActionFilter介绍
为什么可以用ActionFilter来实现这一功能,看一下官方的说明:.net core 中的过滤器允许在执行管道中的特定阶段之前或之后运行代码。可以对全局,也可以对每个控制器或每个操作配置过滤器。
不同的过滤器类型在管道中的不同阶段执行,因此具有各自的场景。根据执行的任务以及执行的请求在管道中的位置,选择要创建的过滤器类型。过滤器在管道中执行,有时也称为过滤管道,在asp .net core 中选择要执行的操作后,执行相应的过滤器。
从上图可以看出一共有四种过滤器:
1、授权过滤器(Authorization filter):用于确定当前请求用户是否被授权。
2、资源过滤器(Resource filter):在授权之后第一个处理请求的过滤器,也是最后一个在请求离开过滤管道时结束请求的过滤器。
3、操作过滤器(Action filter):包装对单个操作方法的调用,并且可以处理传递到操作的参数以及从操作返回的操作结果。
4、异常过滤器(Exception filter):用于对应用程序中未处理的异常应用全局策略。
5、结果过滤器(Result filter):包装单个操作结果的执行,并且尽在操作执行成功时运行。它们必须是围绕视图执行或格式化程序执行的逻辑的理想选择。
ActionFilter
OnActionExecuting:在执行Action之前调用
OnActionExecuted:在执行Action之后调用
public class DESHandlerFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
}
所以只需要在上述过滤器中实现相应的DES加解密方法即可。
在这里有个坑,我们正常的理解是需要去context中拿到httpcontext来获取传入的参数,但实际发现context.HttpContext.Request.Body中是null,经过查阅相关资料发现,微软官方文档有这么一句话:【HttpContext 不是线程安全型。 在处理请求之外读取或写入 HttpContext 的属性可能会导致 NullReferenceException。】
其实这个也很好理解,http请求中的参数只允许最终的执行操作方法来获取,也就是说只允许被获取一次。所以在这里想直接对HttpContext中的参数进行读取并修改是行不通的,但微软官方帮我们封装了一下,看一下ActionExecutingContext 以及ActionContext:
ActionExecutingContext里面有一个ActionArguments,是一个字典,这就是http请求中的真实参数,而参数名称则在ActionContext.ActionDescriptor.Parameters中,所以就可以这么实现:
public class DESHandlerFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
ObjectResult objectResult = context.Result as ObjectResult;
WebApiResponse<string> apiResponse = objectResult.Value as WebApiResponse<string>;
apiResponse.Data = Util.Core.DesHelper.EncryptDES(apiResponse.Data);
objectResult.Value = apiResponse;
}
public void OnActionExecuting(ActionExecutingContext context)
{
var list = context.ActionDescriptor.Parameters;
string obj = Util.Core.DesHelper.DecryptDES(context.ActionArguments[list[0].Name].ToString());
context.ActionArguments[list[0].Name] = obj;
}
}
这里需要说明一下,因为是DES加密,所有的接口均只接受一个string参数,所以在上面的代码中可以context.ActionArguments[list[0].Name].ToString()来获取。如果有多个参数呢,微软官方提供了:自定义模型绑定。具体可以参考:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-5.0.
也可以参考这个链接中的做法:https://www.cnblogs.com/hyl8218/archive/2011/09/27/2192901.html.
最后别忘了在Startup中加上这句:
services.AddControllers(options =>
{
options.Filters.Add<DESHandlerFilter>();
});
结束
使用ActionFilter之后还有一个非常重大的惊喜,Swagger调试的时候再也不用先拿DES加密数据啦,只需要注释掉就跟正常的接口一样啦,实在是太方便了。
services.AddControllers(options =>
{
//options.Filters.Add<DESHandlerFilter>();
});
最后
以上就是长情乐曲为你收集整理的.Net core WebApi 实现对httpcontext中request数据包自定义的全部内容,希望文章能够帮你解决.Net core WebApi 实现对httpcontext中request数据包自定义所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复