我正在尝试注销Web API请求内容,即JSON字符串。我实现了一个ITraceWriter类(示例)并进行了配置,以便在管道中调用Web API。但是,如果我读取request.Content或将其复制到流中以读取它,则该内容对于方法不可用,导致模型为空值。这篇文章稍微谈到了这个问题。有没有人有记录入站Web API请求内容的经验,并知道最佳途径是什么?
谢谢
更新A
我创建了一个简单的Web API示例项目来排除我的项目中的任何问题,但我仍然看到由于记录而导致模型将为空。我通过Fidder多次进行简单测试,并看到我的模型为空。当设置断点时,它可能会工作,这就是为什么我认为存在同步/时间问题的原因。您有没有想法如何使其工作?
标题:
User-Agent: Fiddler
Host: localhost:56824
Content-Type: application/json
Content-Length: 22
正文:
{
"A":1,"B":"test"
}
这是代码:
控制器:
public class ValuesController : ApiController
{
[HttpPost]
public void Post(ValuesModel model)
{
if (model == null)
{
Debug.WriteLine("model was null!");
}
else
{
Debug.WriteLine("model was NOT null!");
}
}
}
型号:
public class ValuesModel
{
public int A { get; set; }
public string B { get; set; }
}
记录器:
public class APITraceLogger : DelegatingHandler
{
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
if (request.Content != null)
{
// This can cause model to be null
request.Content.ReadAsStringAsync().ContinueWith(s =>
{
string requestText = s.Result;
Debug.WriteLine(requestText);
});
// and so can this
//request.Content.ReadAsByteArrayAsync()
// .ContinueWith((task) =>
// {
// string requestText = System.Text.UTF8Encoding.UTF8.GetString(task.Result);
// Debug.WriteLine(requestText);
// });
}
// Execute the request, this does not block
var response = base.SendAsync(request, cancellationToken);
// TODO:
// Once the response is processed asynchronously, log the response data
// to the database
return response;
}
}
在WebApiConfig类中连接记录器:
config.MessageHandlers.Add(new APITraceLogger());
更新 B
如果我更改日志记录器的代码,添加await、async并返回结果,它似乎现在可以工作。看起来是我没有理解异步代码中的某些东西或者真的是一个时机问题或其他原因。
public class APITraceLogger : DelegatingHandler
{
protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
if (request.Content != null)
{
// This does seem to work - is it because it is synchronous? Is this a potential problem?
var requestText = await request.Content.ReadAsStringAsync();
Debug.WriteLine(requestText);
}
// Execute the request, this does not block
var response = base.SendAsync(request, cancellationToken);
// TODO:
// Once the response is processed asynchronously, log the response data
// to the database
return response.Result;
}
}