我正在尝试实施此code example,但在将内容复制到流时会出现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);
}
Fiddler(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();
}
可能是因为内容在这里被读取,它不再可用吗?如果是这样,我怎么能在方法中使它?此处的内容是否与HttpRequestMessage相同? This可能包含答案。
答案 0 :(得分:3)
只是一个猜测,应该发布评论,但我想要包含一个代码片段:
也许您在Post
块中调用using
函数,但不要使用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();
答案 1 :(得分:2)
由于控制器的ActionFilterAttribute's
OnActionExecuting
方法正在调用ReadAsStreamAsync
,因此无法再次阅读内容。我将ReadAsStreamAsync
更改为ReadAsStringAsync
,并且控制器中提供了请求的内容。显然,ReadAsStringAsync缓冲内容,因此它仍然可用。这个link提供了答案。
答案 2 :(得分: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);
}
}
答案 3 :(得分:0)
我解决了这个问题,我的问题是响应在 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();