我尝试捕获原始请求数据以进行问责,并希望将请求正文内容从Request对象中提取出来。
我看过做Request.InputStream的建议,但这个方法在Request对象上不可用。
如何获取Request.Content正文的字符串表示?
答案 0 :(得分:38)
在你对@Kenneth的回答中,你说ReadAsStringAsync()
正在返回空字符串。
那是因为你(或某些东西 - 比如模型绑定器)已经读取了内容,因此Request.Content中内部流的位置就在最后。
你可以做的是:
public static string RequestBody()
{
var bodyStream = new StreamReader(HttpContext.Current.Request.InputStream);
bodyStream.BaseStream.Seek(0, SeekOrigin.Begin);
var bodyText = bodyStream.ReadToEnd();
return bodyText;
}
答案 1 :(得分:12)
您可以通过调用ReadAsStringAsAsync
媒体资源上的Request.Content
来获取原始数据。
string result = await Request.Content.ReadAsStringAsync();
如果您想要在字节或流中存在各种重载。由于这些是异步方法,因此您需要确保控制器是异步的:
public async Task<IHttpActionResult> GetSomething()
{
var rawMessage = await Request.Content.ReadAsStringAsync();
// ...
return Ok();
}
答案 2 :(得分:5)
对于其他未来的用户,他们不想使他们的控制器异步,或者无法访问HttpContext,或者正在使用dotnet core(此答案是我在Google上尝试这样做的第一个答案),以下方法对我有用:
[HttpPut("{pathId}/{subPathId}"),
public IActionResult Put(int pathId, int subPathId, [FromBody] myViewModel viewModel)
{
var body = new StreamReader(Request.Body);
//The modelbinder has already read the stream and need to reset the stream index
body.BaseStream.Seek(0, SeekOrigin.Begin);
var requestBody = body.ReadToEnd();
//etc, we use this for an audit trail
}
答案 3 :(得分:1)
如果您既需要从请求中获取原始内容,又需要在控制器中使用其绑定模型版本,则可能会遇到此异常。
NotSupportedException: Specified method is not supported.
例如,您的控制器可能看起来像这样,让您想知道为什么以上解决方案对您不起作用:
public async Task<IActionResult> Index(WebhookRequest request)
{
using var reader = new StreamReader(HttpContext.Request.Body);
// this won't fix your string empty problems
// because exception will be thrown
reader.BaseStream.Seek(0, SeekOrigin.Begin);
var body = await reader.ReadToEndAsync();
// Do stuff
}
您需要将模型绑定从方法参数中删除,然后手动绑定自己:
public async Task<IActionResult> Index()
{
using var reader = new StreamReader(HttpContext.Request.Body);
// You shouldn't need this line anymore.
// reader.BaseStream.Seek(0, SeekOrigin.Begin);
// You now have the body string raw
var body = await reader.ReadToEndAsync();
// As well as a bound model
var request = JsonConvert.DeserializeObject<WebhookRequest>(body);
}
很容易忘记这一点,过去我已经解决了这个问题,但是现在不得不重新学习解决方案。希望我在这里的答案对自己有一个很好的提醒...