[英]Web Api Request Throws "Error while copying content to a stream."
我正在嘗試實現此代碼示例,但收到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);
}
提琴手(POST):
User-Agent: Fiddler
Host: localhost:23567
Content-Length: 18
Content-Type: application/json; charset=utf-8
Body{"Test":1}
編輯:
我有線索,但需要驗證。 在 Web Api 控制器上,我有一個ActionFilterAttribute
,在它的OnActionExecuting
覆蓋中,有這一行:
public override async void OnActionExecuting(HttpActionContext actionContext)
{
// omitted code
actionContext.Request.Content.ReadAsStreamAsync();
}
會不會是因為內容是在這里閱讀的,所以不能再使用了? 如果是這樣,我如何使其在方法中可用? 這里的Content和HttpRequestMessage一樣嗎? 這可能包含一個答案。
只是一個猜測,應該作為評論發布,但我想包含一個代碼片段:
也許您在using
塊中調用Post
函數,但不要使用await
。
using (HttpRequestMessage request = ...)
{
// Maybe you use this:
Post(request);
// Instead of this
var response = await Post(request);
}
或者你沒有正確處理舊的連接。
另外,嘗試將HttpVersion.Version10
添加到您的請求中,它將標頭請求從Connection: keep-alive
更改為Connection: close
,這可能會導致在某些情況下您重用主機的異常(搜索更多信息)
request.Version = HttpVersion.Version10;
var jsonString = await request.Content.ReadAsStringAsync();
由於控制器的ActionFilterAttribute's
OnActionExecuting
方法正在調用ReadAsStreamAsync
,因此無法再次讀取內容。 我將ReadAsStreamAsync
更改為ReadAsStringAsync
並且請求的內容在控制器中可用。 顯然, ReadAsStringAsync 緩沖內容,因此它仍然可用。 此鏈接提供了答案。
我希望這個(遲到的)帖子有一天會幫助某人......
簡而言之:接受的答案建議將整個文件作為字符串(而不是流)讀取以繞過讀取問題
但是......將文件作為字符串讀取並不是一個好主意
我想通了,與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);
}
}
我解決了這個問題,我的問題是響應在 gzip 中:
var handler = new HttpClientHandler();
if (handler.SupportsAutomaticDecompression)
{
handler.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate;
}
client = new HttpClient(handler);
var content = new FormUrlEncodedContent(valoresPost);
var response = await client.PostAsync(url, content);
var contenidoPdf = await response.Content.ReadAsByteArrayAsync();
我正在添加到對話中,因為我在不同的上下文中遇到了這個錯誤。 對我來說,我有一個從我的網絡應用程序到一個單獨的 API 的現有調用。 它以前可以正常工作然后停止,我收到此錯誤並且無法找到原因。 結果是我的實體框架中的循環引用,本質上是兩個不應該存在的對象之間的導航屬性。 它並沒有破壞 API,因為我認為 EF 具有導航屬性將填充的深度的默認配置,以防止堆棧溢出,但它肯定已經使接收端的流不堪重負並導致連接超時。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.