使用自宿主OWIN

项目中要做日志过滤器

新建类ApiLogAttribute

继承ActionFilterAttribute

ApiLogAttribute :  ActionFilterAttribute

public override Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            string result = null;
            Stream stream = actionContext?.Request?.Content?.ReadAsStreamAsync().Result;
            if(stream=null)                return base.OnActionExecutingAsync(actionContext,cancellationToken);
            stream.Position = 0L;             Encoding encoding = Encoding.UTF8;            /* 这个StreamReader不能关闭,也不能dispose 因为你关掉后,后面的管道 或拦截器就没办法读取了 */             var reader = new StreamReader(stream, encoding);             result = reader.ReadToEnd();             /* 这里也要注意: stream.Position = 0;               当你读取完之后必须把stream的位置设为开始                因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。             */             stream.Position = 0L;             Console.WriteLine(result);             return base.OnActionExecutingAsync(actionContext, cancellationToken); }

结果发现stream Position 无法设置,CanSeek为false

用 流复制也不管用

MemoryStream stream = new MemoryStream();
Stream.CopyToAsync(stream);
始终读取不到内容

最后读取文档得知 OWIN 中 Request 的content 只能读取一次,已经被解析,无法再次读取

搜索了一番

https://stackoverflow.com/questions/31389781/read-request-body-twice/31395692#31395692

解决办法如下

在Startup中添加添加中间件

这里的流还没有被读取过,直接复制一份CanSeek为false的stream 流 ,进行替换

//Request stream重用
            app.Use(async (context, next) =>
            {
                // Keep the original stream in a separate
                // variable to restore it later if necessary.
                var stream = context.Request.Body;

                // Optimization: don't buffer the request if
                // there was no stream or if it is rewindable.
                if (stream == Stream.Null || stream.CanSeek)
                {

                    await next.Invoke();

                    return;
                }

                try
                {
                    using (var buffer = new MemoryStream())
                    {
                        // Copy the request stream to the memory stream.
                        await stream.CopyToAsync(buffer);

                        // Rewind the memory stream.
                        buffer.Position = 0L;

                        // Replace the request stream by the memory stream.
                        context.Request.Body = buffer;

                        // Invoke the rest of the pipeline.
                        await next.Invoke();
                    }
                }

                finally
                {
                    // Restore the original stream.
                    context.Request.Body = stream;
                }
            });

或者 在过滤器中 通过如下放法 直接 取出已经被解析的参数

/// <summary>
        /// 读取request 的提交内容
        /// </summary>
        /// <param name="actionContext"></param>
        /// <returns></returns>
        public string GetRequestValues(HttpActionContext actionContext)
        {
            string result = null;
            foreach (var arg in actionContext.ActionArguments)
            {
                result += $"key={arg.Key};";
                result += $"value={JsonConvert.SerializeObject(arg.Value)};{Environment.NewLine}";
            }

            return result;
        }

Web API Request Content多次读取的更多相关文章

  1. Routing in ASP.NET Web API和配置文件的设定读取

    Routing Tables In ASP.NET Web API, a controller is a class that handles HTTP requests. The public me ...

  2. 【ASP.NET Web API教程】6.3 内容协商

    本文是Web API系列教程的第6.3小节 6.3 Content Negotiation 6.3 内容协商 摘自:http://www.asp.net/web-api/overview/format ...

  3. Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)

    导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文主要来讲解以下内容: ...

  4. Parameter Binding in ASP.NET Web API(参数绑定)

    Parameter Binding in ASP.NET Web API(参数绑定) 导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnbl ...

  5. Web API 方法的返回类型、格式器、过滤器

    一.Action方法的返回类型 a) 操作方法的返回类型有四种:void.简单或复杂类型.HttpResponseMessage类型.IHttpActionResult类型. b) 如果返回类型为vo ...

  6. 浅谈 asp.net core web api

    希望通过本文能够了解如下内容: ControllerBase Attributes Action的返回值类型 ControllerBase 当我们开始实际上项目, 真正实操 anc 时, 肯定会用到 ...

  7. 一张图说明 Web Api 参数绑定默认规则

    请求如下: 控制器如下: 慎重说明:不管请求方式是 get 还是 post , 简单类型的参数,如 name 和 id ,其值都是从 url 里面去取. Web API 从 url 还是 body 获 ...

  8. Dynamics 365本地部署版本配置OAuth 2 Password Grant以调用Web API

    微软动态CRM专家罗勇 ,回复330或者20190504可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 根据官方建议,不要再使用Dynamics 365 Custome ...

  9. 温故知新,使用ASP.NET Core创建Web API,永远第一次

    ASP.NET Core简介 ASP.NET Core是一个跨平台的高性能开源框架,用于生成启用云且连接Internet的新式应用. 使用ASP.NET Core,您可以: 生成Web应用和服务.物联 ...

随机推荐

  1. 树链剖分详解(洛谷模板 P3384)

    洛谷·[模板]树链剖分 写在前面 首先,在学树链剖分之前最好先把 LCA.树形DP.DFS序 这三个知识点学了 emm还有必备的 链式前向星.线段树 也要先学了. 如果这三个知识点没掌握好的话,树链剖 ...

  2. dubbo和zikkeper的使用

    1.先来一段异常看看:No provider available for the service 16:05:25.755 [localhost-startStop-1] WARN o.s.w.c.s ...

  3. python从爬虫基础到爬取网络小说实例

    一.爬虫基础 1.1 requests类 1.1.1 request的7个方法 requests.request() 实例化一个对象,拥有以下方法 requests.get(url, *args) r ...

  4. Javascript arguments.callee和caller的区别

    一.callee 在学习callee之前,需要先学习arguments. arguments: 含义:该对象代表正在执行的函数和调用它的函数的参数. 语法: 1 [function.]argument ...

  5. JSR286portlet中使用Ajax的方法

    JSR286portlet支持Ajax 一个平常的portlet先,jsr286类型. /Train01/WebContent/WEB-INF/portlet.xml <?xml version ...

  6. django日志,django-crontab,django邮件模块

    django 日志 四大块,格式器,过滤器,处理器,日志管理器 LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatt ...

  7. 还在期待安卓9.0吗?Android 10.0要来了

    目前,美国 Google公司的 AndroidP (安卓9.0),已经正式全面推出有几个多月了.众多手机品牌厂商也都在积极的进行更新适配 Android 9.0 系统(修改UI界面也算是二次开发,嗯) ...

  8. Jmeter性能测试之分布式(五)

    Jmeter是纯Java开发的开源性能测试工具, Java程序是很吃内存的, 有时候一台负载机给服务器的压力是不够的, 需要很多台同时负载, 这个时候就需要用到分布式了. 1. 组网图大概就是这样的 ...

  9. [转]一个普通IT人的十年回顾---金旭亮

    金旭亮老师十年体会,很有收获.转自网络. 金旭亮于1989年与超级解霸的开发者梁肇新同时迈入广西大学的校门,却走了一条与其不同的路. 1994年起开始自学计算机专业本科课程,并开始编程,从未间断,迄今 ...

  10. thinkphp使用PHPExcel导出

    thinkphp3. 将PHPExcel下载包放在项目\ThinkPHP\Library\Vendor\PHPExcel thinkphp5 将PHPExcel下载包放在项目\vendor\PHPEx ...