使用自宿主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. Notepad++崩溃后文件内容找不到问题

    也许是因为Ctrl + s 摁太多太频繁,一不小心Notepad++崩溃了 重启后发现原来的文件还在,但是文件内容全部都被清空了 我没有手动备份这个文件, 如何找回??? 点击设置,首选项,里面有个备 ...

  2. Linux 踩过的坑系列-01

    关于默认网关的添加.记得楼主之前有一次,无意之间,也不知道做了什么删除文件里面内容的操作,配置好静态IP之后上不了外网.翻阅个各种资料都是没有找到问题.最后发现问题在于配置的虚拟机网卡文件的网关打错了 ...

  3. python跨网段遍历枚举IP地址(转)

    转载链接:https://blog.csdn.net/u013042248/article/details/53165508 0x01 代码思路: 利用二进制遍历: 1.将IP地址分割,每一块转换为8 ...

  4. iTOP-4412开发板-串口转接小板的使用文档

    本文档介绍如何使用 迅为iTOP-4412 精英版如何使用串口转接板,串口小板如下所示.和串口转接板模块相关的资料如下:“iTOP-4412-Android-串口测试文档(升级版)_V2.X.zip” ...

  5. 51nod--1072 威佐夫游戏 (博弈论)

    题目: 1072 威佐夫游戏 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆中取任意个或从2堆中取相同 ...

  6. Hibernate查询返回自定义VO的两种方式

    说明:createQuery用的hql语句进行查询,createSQLQuery用sql语句查询: 前者以hibernate生成的Bean为对象装入list返回:后者则是以对象数组进行存储: 一.通过 ...

  7. vue ajax返回html代码不渲染解决

    <span v-html='lists.html'></span>

  8. JavaScript入门(基础)

    一.JS语言介绍 1.概述 浏览器脚本语言 可以编写运行在浏览器上的代码程序 属于解释性.弱语言类型编程语言 2.组成 ES语法:ECMAScript.主要版本有ES5和ES6 DOM:文档对象模型( ...

  9. VUE项目的目录关系

    1.页面中只有一个index.html. 2.一个js文件.在路由中. 3.主要的app.vue. 4.最后就是可以放多个vue文件的~~(一个页面对应一个vue文件,一个vue组件对应一个js中的i ...

  10. [方案]基于Zynq WiFi方案构建

    基于Zynq系列,搭建无线传输平台 1) 2.4G 2) 5G AC