.Net core WebApi 实现对httpcontext中request数据包自定义

前言

最近公司有个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>();
                    });
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值