Web API Request Content多次读取
使用自宿主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多次读取的更多相关文章
- 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 ...
- 【ASP.NET Web API教程】6.3 内容协商
本文是Web API系列教程的第6.3小节 6.3 Content Negotiation 6.3 内容协商 摘自:http://www.asp.net/web-api/overview/format ...
- 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. 本文主要来讲解以下内容: ...
- Parameter Binding in ASP.NET Web API(参数绑定)
Parameter Binding in ASP.NET Web API(参数绑定) 导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnbl ...
- Web API 方法的返回类型、格式器、过滤器
一.Action方法的返回类型 a) 操作方法的返回类型有四种:void.简单或复杂类型.HttpResponseMessage类型.IHttpActionResult类型. b) 如果返回类型为vo ...
- 浅谈 asp.net core web api
希望通过本文能够了解如下内容: ControllerBase Attributes Action的返回值类型 ControllerBase 当我们开始实际上项目, 真正实操 anc 时, 肯定会用到 ...
- 一张图说明 Web Api 参数绑定默认规则
请求如下: 控制器如下: 慎重说明:不管请求方式是 get 还是 post , 简单类型的参数,如 name 和 id ,其值都是从 url 里面去取. Web API 从 url 还是 body 获 ...
- Dynamics 365本地部署版本配置OAuth 2 Password Grant以调用Web API
微软动态CRM专家罗勇 ,回复330或者20190504可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 根据官方建议,不要再使用Dynamics 365 Custome ...
- 温故知新,使用ASP.NET Core创建Web API,永远第一次
ASP.NET Core简介 ASP.NET Core是一个跨平台的高性能开源框架,用于生成启用云且连接Internet的新式应用. 使用ASP.NET Core,您可以: 生成Web应用和服务.物联 ...
随机推荐
- eclipse hadoop环境搭建 查看HDFS文件内容
1.下载插件 hadoop-eclipse-plugin-2.5.2.jar放入eclipse/plugin 2.准备hadoop-2.5.0-cdh5.3.6 使用WinSCP远程连接虚拟机,复制h ...
- 记事本 HTML
又学了一遍HTML,感觉轻松了好多,个人感觉HTML和画画差不多,只要有了想法,画出来其实并不难. 头部信息<head> 头部信息并不是给我们看的,而是给浏览器看的,当浏览器看到之后,才好 ...
- oracle利用redo恢复
oracle媒介恢复(Media Recovery) 官方资料 https://docs.oracle.com/database/121/ADMQS/GUID-CBC5870F-2C9A-4F67-B ...
- Beta冲刺(3/7)
目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:beta冲刺(3/7) 团队部分 后敬甲(组长) 过去两天完成了哪些任务 整理博客 ppt模板 接下来的计划 做好机动. ...
- Linux Django项目测试
步骤 django项目: 依赖包 [root@web01 ~]# yum install openssl-devel bzip2-devel expat-devel gdbm-devel readli ...
- 【原创】大数据基础之Zookeeper(3)选举算法
提到zookeeper选举算法,就不得不提Paxos算法,因为zookeeper选举算法是Paxos算法的一个变种: Paxos要解决的问题是:在一个分布式网络环境中有众多的参与者,但是每个参与者都不 ...
- 【由浅入深理解java集合】(四)——集合 Queue
今天我们来介绍下集合Queue中的几个重要的实现类.关于集合Queue中的内容就比较少了.主要是针对队列这种数据结构的使用来介绍Queue中的实现类. Queue用于模拟队列这种数据结构,队列通常是指 ...
- 《剑指offer》第一个只出现一次的字符
本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:
- java---- XMLEncoder 和 XMLDecoder 和 xSteam工具使用
XMLEncoder: 将对象写入XML数据中 import org.dom4j.DocumentException; import java.beans.XMLEncoder; import jav ...
- 数位dp-入门模板题 hdu2089
#include<bits/stdc++.h> using namespace std; ][],n,m; void init(){//dp[i][j]:i位的数,最高位是j dp[][] ...