How do I get the raw request body from the Request

2020-02-05 06:24发布

I'm trying to capture the raw request data for accountability and want to pull the request body content out of the Request object.

I've seen suggestions doing a Request.InputStream, but this method is not available on the Request object.

Any idea of how to get a string representation of the Request.Content body?

Watch variable

3条回答
Viruses.
2楼-- · 2020-02-05 06:33

You can get the raw data by calling ReadAsStringAsAsync on the Request.Content property.

string result = await Request.Content.ReadAsStringAsync();

There are various overloads if you want it in a byte or in a stream. Since these are async-methods you need to make sure your controller is async:

public async Task<IHttpActionResult> GetSomething()
{
    var rawMessage = await Request.Content.ReadAsStringAsync();
    // ...
    return Ok();
}

EDIT: if you're receiving an empty string from this method, it means something else has already read it. When it does that, it leaves the pointer at the end. An alternative method of doing this is as follows:

public IHttpActionResult GetSomething()
{
    var reader = new StreamReader(Request.Body);
    reader.BaseStream.Seek(0, SeekOrigin.Begin); 
    var rawMessage = body.ReadToEnd();

    return Ok();
}

In this case, your endpoint doesn't need to be async (unless you have other async-methods)

查看更多
Bombasti
3楼-- · 2020-02-05 06:48

In your comment on @Kenneth's answer you're saying that ReadAsStringAsync() is returning empty string.

That's because you (or something - like model binder) already read the content, so position of internal stream in Request.Content is on the end.

What you can do is this:

public static string RequestBody()
{
    var bodyStream = new StreamReader(HttpContext.Current.Request.InputStream);
    bodyStream.BaseStream.Seek(0, SeekOrigin.Begin);
    var bodyText = bodyStream.ReadToEnd();
    return bodyText;
}
查看更多
干净又极端
4楼-- · 2020-02-05 06:51

For other future users who do not want to make their controllers asynchronous, or cannot access the HttpContext, or are using dotnet core (this answer is the first I found on Google trying to do this), the following worked for me:

[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
}
查看更多
登录 后发表回答