San*_*ndo 14 c# rest web-services asp.net-web-api
在Controller中的Action中尝试对象时,偶尔似乎是null.我发现,这是由于ReadAsStringAsync()在SendAsync()的覆盖DelegatingHandler.问题在于内容.当我的客户端发送一个内容正文并在记录器中读取它时,它永远不会被Controller Action Invoker读取(或者可能在某个地方JsonFormatter).我怀疑后续调用Content.ReadAsStringAsync()不会抛出异常,但也不会返回预期的内容体(返回一些信息表明异步读取已完成).
但是我的问题仍然存在,因为我想[FromBody]在一个动作中读取一个参数,当它Content.ReadStringAsync获得RaceCondition的时候它是null DelegatingHandler.当JsonFormatter虽然赢了,我得到的对象,但是这是罕见的(只在服务启动).
这是我的DelegatingHandler代码:
public class LogHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var apiRequest = new WebApiUsageRequest(request);
WriteLog(apiRequest);
request.Content.ReadAsStringAsync().ContinueWith(t =>
{
apiRequest.Content = t.Result;
WriteLog(apiRequest);
});
return base.SendAsync(request, cancellationToken).ContinueWith(task =>
{
var apiResponse = new WebApiUsageResponse(task.Result);
apiResponse.Content = task.Result.Content != null ? task.Result.Content.ReadAsStringAsync().Result : null;
WriteLog(apiResponse);
return task.Result;
});
}
}
Run Code Online (Sandbox Code Playgroud)
有没有人有解决这个问题的线索?
这是设计的.在ASP.NET Web API中,正文内容被视为只能读取一次的仅向前流.
您可能尝试使用ASP.NET Web API跟踪,但我还没有使用POST请求进行测试,所以我不确定它是如何跟踪请求正文(它确实是跟踪GET请求的参数).你可以在这里阅读更多:
ReadAsStreamAsync方法返回正文内容.
var body = string.Empty;
using (var reader = new StreamReader(request.Content.ReadAsStreamAsync().Result))
{
reader.BaseStream.Seek(0, SeekOrigin.Begin);
body = reader.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)
这是我最终做的:
public string SafelyReadContent(HttpRequestMessage request)
{
var stream = request.Content.ReadAsStreamAsync().Result;
var reader = new StreamReader(stream);
var result = reader.ReadToEnd();
stream.Seek(0, SeekOrigin.Begin);
return result;
}
Run Code Online (Sandbox Code Playgroud)
@pirimoglu 使用“using”块的答案对我不起作用,因为当读取器被释放时,底层流也被关闭。
| 归档时间: |
|
| 查看次数: |
13287 次 |
| 最近记录: |