2016-03-01 415 views
6

我试图执行此code example,但获得HttpRequestException - “错误,同时将内容复制到流。”当调用ReadAsStringAsync()方法时。内部例外是“无法访问处置对象”。我正在使用Fiddler来提出请求。我不明白。有人可以解释为什么我得到这个例外并提供解决方案吗?Web Api请求引发“将内容复制到流时出错”。

的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); 
} 

提琴手(POST):

User-Agent: Fiddler 
Host: localhost:23567 
Content-Length: 18 
Content-Type: application/json; charset=utf-8 
Body{"Test":1} 

编辑:

我有一个线索,但需要验证。在网络API控制器,我有一个ActionFilterAttribute,并在其OnActionExecuting覆盖,有这样一行:

public override async void OnActionExecuting(HttpActionContext actionContext) 
{ 
    // omitted code 
    actionContext.Request.Content.ReadAsStreamAsync(); 
} 

难道是因为这里的内容读取,它再次不可用?如果是这样,我该如何使它在方法中可用?这里的内容是否与HttpRequestMessage相同? This可能包含答案。

+0

你是怎么调用这个方法的? –

+0

@YuvalItzchakov ...我正在使用Fiddler –

+0

这种方法是Web API操作吗? –

回答

1

由于控制器的ActionFilterAttribute'sOnActionExecuting方法正在调用ReadAsStreamAsync,内容不能再被读取。我将ReadAsStreamAsync更改为ReadAsStringAsync,并且请求的内容在控制器中可用。可以看出,ReadAsStringAsync缓冲了内容,所以它仍然可用。 link提供了答案。

1

只是一个客人,应该张贴的评论,但我想包括代码sipnet:

也许你调用一个using块内Post功能,但不使用await

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

    // Instead of this 
    var response = await Post(request); 
} 

或者您没有正确处置旧连接。

同时,尽量增加HttpVersion.Version10您的要求,这改变头请求从Connection: keep-aliveConnection: close,它可以在你重新使用主机一些情况下会引起异常(搜索获得更多信息)

request.Version = HttpVersion.Version10; 
var jsonString = await request.Content.ReadAsStringAsync(); 
+0

谢谢,没有这些运气 –

1

我希望这(晚)职位将帮助别人一天......

简而言之:接受的答案建议读取整个文件作为字符串(而不是流),以绕过读取问题

但是...读取文件作为一个字符串是不是一个好主意

我想通了,与MultipartMemoryStreamProvider更换MultipartFormDataStreamProvider的伟大工程 - 让你读你上传的文件所需

我的代码(至少它的相关部分)

[HttpPost] 
    [Route("upload/file")] // you may replace this route to suit your api service 
    public async Task<IHttpActionResult> Upload() 
    { 
     if (!Request.Content.IsMimeMultipartContent("form-data")) 
     { 
      return BadRequest("Unsupported media type"); 
     } 

     try 
     { 
      var provider = new MultipartMemoryStreamProvider(); 

      await Request.Content.ReadAsMultipartAsync(provider); 

      if (provider.Contents.Count == 0) return InternalServerError(new Exception("Upload failed")); 

      var file = provider.Contents[0]; // if you handle more then 1 file you can loop provider.Contents 

      var buffer = await file.ReadAsByteArrayAsync(); 

      // .. do whatever needed here 

      return Ok(); 

     } 
     catch (Exception ex) 
     { 
      return BadRequest(ex.GetBaseException().Message); 
     } 
    }