如何使用.net 4 api端点

时间:2016-02-23 22:29:28

标签: c# asp.net-web-api

我尝试捕获原始请求数据以进行问责,并希望将请求正文内容从Request对象中提取出来。

我看过做Request.InputStream的建议,但这个方法在Request对象上不可用。

如何获取Request.Content正文的字符串表示?

Watch variable

4 个答案:

答案 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);
}

很容易忘记这一点,过去我已经解决了这个问题,但是现在不得不重新学习解决方案。希望我在这里的答案对自己有一个很好的提醒...