我正在尝试注销 Web API 请求内容——即 json 字符串。我实现了一个 ITraceWriter 类(示例)并对其进行了配置,以便 Web API 在管道中调用它。但是,如果我读取 request.Content 或复制到流中进行读取,则该方法无法使用导致 null 模型的方法。 这篇文章稍微讨论了这个问题。任何人都有注销入站 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
如果我将记录器更改为以下代码,添加等待、异步并返回结果,它似乎现在正在工作。似乎我在异步代码中不理解的东西或真正的时间问题或其他东西。
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;
}
}