• ASP.NET Core 各版本 中间件或过滤器中获取Post参数方法


    ContentType:application/json

    一、net core2.1 、3.1

    1、权限(AuthorizationFilters)验证器中读取并只读取有一次请求串的方法

    1. HttpRequest request = context.HttpContext.Request;
    2. // post请求方式获取请求参数,.net core 2.0 不支持.Form 直接获取
    3. Stream stream = request.Body;
    4. byte[] buffer = new byte[request.ContentLength.Value];
    5. stream.Read(buffer, 0, buffer.Length);
    6. string querystring = Encoding.UTF8.GetString(buffer);

    2、当在动作过滤器(ActionFilter)或者需要多次读取 request.body 的时候,.net core 可以通过调用request.EnableRewind()实现,可以重置读取位置 ,但是要在权限验证器中添加

    1. ///
    2. /// 请求验证,当前验证部分不要抛出异常,ExceptionFilter不会处理
    3. ///
    4. /// 请求内容信息
    5. public void OnAuthorization(AuthorizationFilterContext context)
    6. {
    7. HttpRequest request = context.HttpContext.Request;
    8. request.EnableRewind();
    9. request.Body.Position = 0;
    10. }

    3、在任意想要读取的位置重复读取

    1. if (context.HttpContext.Request.ContentType == "application/json")
    2. {
    3. Stream straem = context.HttpContext.Request.Body;
    4. Encoding encoding = Encoding.UTF8;
    5. string data = string.Empty;
    6. using (StreamReader reader = new StreamReader(straem, encoding))
    7. {
    8. //data就是post传过来的值json格式
    9. data = reader.ReadToEndAsync().Result;
    10. }
    11. }
    1. ///
    2. /// 根据请求信息返回请求串
    3. ///
    4. /// 请求信息
    5. /// 请求串
    6. public static string QueryString(HttpRequest request)
    7. {
    8. // post 请求方式获取请求参数方式
    9. if (request.Method.ToLower().Equals("post"))
    10. {
    11. try
    12. {
    13. // post请求方式获取请求参数,.net core 2.0 不支持.Form 直接获取
    14. Stream stream = request.Body;
    15. byte[] buffer = new byte[request.ContentLength.Value];
    16. stream.Read(buffer, 0, buffer.Length);
    17. string querystring = Encoding.UTF8.GetString(buffer);
    18. return querystring;
    19. }
    20. catch
    21. {
    22. return string.Empty;
    23. }
    24. }
    25. else
    26. {
    27. return request.QueryString.Value;
    28. }
    29. }
    1. public class OperateLogFilter : ActionFilterAttribute
    2. {
    3. private Stopwatch Stopwatch { get; set; }
    4. public override void OnActionExecuting(ActionExecutingContext context)
    5. {
    6. base.OnActionExecuting(context);
    7. Stopwatch = new Stopwatch();
    8. Stopwatch.Start();
    9. }
    10. public override void OnActionExecuted(ActionExecutedContext context)
    11. {
    12. base.OnActionExecuted(context);
    13. Stopwatch.Stop();
    14. string apiName = context.ActionDescriptor.DisplayName;
    15. double elapsed = Stopwatch.Elapsed.TotalMilliseconds;
    16. // 获取请求参数
    17. HttpRequest request = context.HttpContext.Request;
    18. //-- 由于mvc里已经读过request.Body,现在它的position在末尾
    19. // 允许重新读body
    20. request.EnableRewind();
    21. // 将position置到开始位置
    22. request.Body.Position = 0;
    23. // 读取body的数据流,并转为string
    24. var reader = new StreamReader(request.Body);
    25. var contentFromBody = reader.ReadToEnd();
    26. }
    27. }

    二、net 5.0

    由于.net 5.0 倒带方式发生了改变,在asp.net core web api 项目中,框架为.NET5,启动倒带方式,为 request.EnableBuffering()
    但是在过滤器中使用此方法时出现异常,request.body的长度总是为0,说明在请求到达过滤器时Steam已经被读取了。

    错误代码:

    1. public class TestFilter : ActionFilterAttribute
    2. {
    3. public override void OnActionExecuting(ActionExecutingContext context)
    4. {
    5. base.OnActionExecuting(context);
    6. var request = context.HttpContext.Request;
    7. //启动倒带方式
    8. request.EnableBuffering();
    9. if (request.Method.ToLower().Equals("post"))
    10. {
    11. request.Body.Position = 0;
    12. using var requestReader = new StreamReader(request.Body);
    13. var requestContent = requestReader.ReadToEnd();
    14. request.Body.Position = 0;
    15. }
    16. }
    17. public override void OnActionExecuted(ActionExecutedContext context)
    18. {
    19. base.OnActionExecuted(context);
    20. }
    21. }

    解决方法:

    1、在项目的Startup类中的Configure方法中添加如下配置:

    1. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    2. {
    3. //其他代码
    4. //启动倒带方式
    5. app.Use(next => context =>
    6. {
    7. context.Request.EnableBuffering();
    8. return next(context);
    9. });
    10. app.UseEndpoints(endpoints =>
    11. {
    12. endpoints.MapControllers();
    13. });
    14. }

    注意:
    EnableBuffering的配置一定要在UseEndpoints的前面;

    2、修改过后滤器中的代码:

    1. public override void OnActionExecuting(ActionExecutingContext context)
    2. {
    3. base.OnActionExecuting(context);
    4. var request = context.HttpContext.Request;
    5. if (request.Method.ToLower().Equals("post"))
    6. {
    7. request.Body.Position = 0;
    8. using var requestReader = new StreamReader(request.Body);
    9. var requestContent = requestReader.ReadToEnd();
    10. request.Body.Position = 0;
    11. }
    12. }

    三、Post Form和Get方法获取参数

    1. switch (context.HttpContext.Request.Method.ToUpper())
    2. {
    3. case "GET":
    4. operateEntity.ExecuteParam = context.HttpContext.Request.QueryString.Value.ParseToString();
    5. break;
    6. case "POST":
    7. Dictionary<string, string> param = new Dictionary<string, string>();
    8. foreach (var item in context.ActionDescriptor.Parameters)
    9. {
    10. var itemType = item.ParameterType;
    11. if (itemType.IsClass && itemType.Name != "String")
    12. {
    13. PropertyInfo[] infos = itemType.GetProperties();
    14. foreach (PropertyInfo info in infos)
    15. {
    16. if (info.CanRead)
    17. {
    18. var propertyValue = context.HttpContext.Request.Form[info.Name];
    19. if (!param.ContainsKey(info.Name))
    20. {
    21. if (!string.IsNullOrEmpty(propertyValue))
    22. {
    23. param.Add(info.Name, propertyValue);
    24. }
    25. }
    26. }
    27. }
    28. }
    29. }
    30. break;
    31. }

  • 相关阅读:
    Apache Doris的性能优化之Runtime Filter
    java计算机毕业设计银行客户管理源程序+mysql+系统+lw文档+远程调试
    6. 微服务之Gateway网关
    JAVA基础知识Fundamental
    第十八章 使用工作队列管理器(一)
    《MongoDB入门教程》第04篇 MongoDB客户端
    java.sql.SQLSyntaxErrorException: Unknown database ‘数据库名‘
    单链表及其所有操作(无哨兵位)
    Vue 源码解读(12)—— patch
    平板电脑也可以学python吗?10 个Python 编辑器,,让编程更贴近生活~
  • 原文地址:https://blog.csdn.net/hwt0101/article/details/80893212