使用自宿主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. centos7.2 环境下两个数据库的安装部署

    首先假如服务器上已经有一个 数据库mysql5.6.29,端口是3306. 接下来在安装一个mysql数据库,端口是3307的. 一:创建mysql编译目录 mkdir /usr/local/mysq ...

  2. scikit-learn 决策树 分类问题

    1.Demo from sklearn import tree import pydotplus import numpy as np #李航p59表数据 #年龄,有工作,有自己房子,信贷情况,类别 ...

  3. EmbeddedSolrServer的使用与solor6.3.0的使用

    1.    到solr官网下载对应版本的solr: https://lucene.apache.org/solr/ 我下载的是:6.3.0版本(需要JDK8),solr默认集成了jetty容器,而且在 ...

  4. js中子页面父页面方法 变量相互调用(转)

    原文:https://www.cnblogs.com/huangshuqiang/p/5734358.html (1)子页面调用父页面的方法或者变量: window.parent.方法()或者变量名w ...

  5. 27)django-form操作示例(动态Select数据,自定义字段验证,全局验证等)

    1)普通传递select数据 # -*- coding:utf-8 -*- __author__ = 'shisanjun' from django import forms from django. ...

  6. javascript事件委托的原理与实现

    事件委托 事件流 捕获:查找目标元素: 目标:执行目标的事件: 冒泡:依次执行祖先元素的事件. onmouseenter和onmouseleave不支持冒泡: onmouseover和onmouseo ...

  7. 如何给PDF设置全屏动画

    PPT文件可以播放全屏,并且可以实现飞入.分割.闪烁等动画模式播放.那么PDF文件可以吗?我们想要给PDF文件加入动画效果应该怎么做呢,也有很多的小伙伴不知道该怎么把PDF文件切换为全屏动画模式想要知 ...

  8. Git使用八:创建和切换分支

    git的分支 与svn对比 克隆一份全新的目录以同样拥有 5 个分支来说,SVN 是同时复制 5 个版本的文件,也就是说重复 5 次同样的动作.而 Git 只是获取文件的每个版本的元素,然后只载入主要 ...

  9. Python学习笔记九

    Python学习笔记之九 为什么要有操作系统 管理硬件,提供接口. 管理调度进程,并且将多个进程对硬件的竞争变得有序. 操作系统发展史 第一代计算机:真空管和穿孔卡片 没有操作系统,所有的程序设计直接 ...

  10. thinkphp5调用阿里大鱼短信

    :在Controller.php public function send() { if (request()->isPost()) { $phone = input('post.phone/s ...