Web Api请求在将内容复制到流时会出现"错误".

Big*_*ddy 10 c# asp.net-web-api

我正在尝试实现此代码示例,但得到HttpRequestException- " 将内容复制到流时出错 ".ReadAsStringAsync()调用方法时 内部异常是" 无法访问已处置的对象".我正在使用Fiddler来提出请求.我不明白.有人可以解释为什么我得到这个例外并提供解决方案吗?

Web Api方法:

public async Task<HttpResponseMessage> Post(HttpRequestMessage request)
{
    try
    {
        var jsonString = await request.Content.ReadAsStringAsync();
    }
    catch (Exception ex)
    {                
        throw;
    }
    return new HttpResponseMessage(HttpStatusCode.Created);
}
Run Code Online (Sandbox Code Playgroud)

提琴手(POST):

User-Agent: Fiddler
Host: localhost:23567
Content-Length: 18
Content-Type: application/json; charset=utf-8
Body{"Test":1}
Run Code Online (Sandbox Code Playgroud)

编辑:

我有一个线索,但需要验证.在Web Api控制器上,我有一个ActionFilterAttribute并且在它的OnActionExecuting覆盖中,有这一行:

public override async void OnActionExecuting(HttpActionContext actionContext)
{
    // omitted code
    actionContext.Request.Content.ReadAsStreamAsync();
}
Run Code Online (Sandbox Code Playgroud)

可能是因为内容在这里被读取,它再也无法使用?如果是这样,我怎么能在方法中使它?此处的内容是否与HttpRequestMessage相同? 可能包含答案.

Tuy*_*ham 6

只是一个猜测,应该作为评论发布,但我想包含一个代码片段:

也许您Postusing块内调用函数,但不要使用await.

using (HttpRequestMessage request = ...)
{
    // Maybe you use this:
    Post(request);

    // Instead of this
    var response = await Post(request);
}
Run Code Online (Sandbox Code Playgroud)

或者你没有正确处理旧的连接。

另外,尝试添加HttpVersion.Version10到您的请求中,它将标头请求从Connection: keep-aliveto更改为Connection: close,这可能会导致在某些情况下您重用主机的异常(搜索更多信息)

request.Version = HttpVersion.Version10;
var jsonString = await request.Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud)


Big*_*ddy 2

因为控制器的ActionFilterAttribute's OnActionExecuting方法正在调用ReadAsStreamAsync,所以无法再次读取内容。我更改ReadAsStreamAsyncReadAsStringAsync并且请求的内容在控制器中可用。显然,ReadAsStringAsync 缓冲了内容,因此它仍然可用。这个链接提供了答案。