Bry*_*yan 9 asp.net-mvc asp.net-web-api
我正在尝试注销Web API请求内容 - 即json字符串.我实现了一个ITraceWriter类(示例)并对其进行了配置,以便Web API在管道中调用它.但是,如果我读取请求.内容或复制到流中读取它不适用于导致空模型的方法. 这篇文章稍微谈到了这个问题.任何人都有登出入站Web API请求内容的经验,并知道最佳方法是什么?
谢谢
更新A.
我创建了一个简单的示例Web API项目来排除项目中的任何内容,我仍然看到由于日志记录,模型将为null.我只是通过Fidder发布测试连续几次,看看我的模型是否为null.有了断点,它可能会起作用,这就是为什么我认为存在同步/计时问题.有关如何使其工作的任何想法?
标题:
User-Agent: Fiddler
Host: localhost:56824
Content-Type: application/json
Content-Length: 22
Run Code Online (Sandbox Code Playgroud)
身体:
{
"A":1,"B":"test"
}
Run Code Online (Sandbox Code Playgroud)
这是代码:
控制器:
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!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
模型:
public class ValuesModel
{
public int A { get; set; }
public string B { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
记录仪:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在WebApiConfig类中连接记录器:
config.MessageHandlers.Add(new APITraceLogger());
Run Code Online (Sandbox Code Playgroud)
更新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;
}
}
Run Code Online (Sandbox Code Playgroud)
正如Filip在该帖子中提到的,ReadAsStringAsync或ReadAsByteArrayAsync方法在内部缓冲请求内容.这意味着即使您的传入请求的流类型是非缓冲流,您也可以安全地在消息处理程序中执行ReadAsStringAsync/ReadAsByteArrayAsync,并且还期望模型绑定正常工作.
默认情况下,请求的流在webhost和selfhost情况下都会缓冲.但是,如果您想检查是否使用ReadAsStringAsync/ReadAsByteArrayAsync并且模型biding即使在非缓冲模式下也能正常工作,您可以执行以下操作来强制执行非缓冲模式:
public class CustomBufferPolicySelector : WebHostBufferPolicySelector
{
public override bool UseBufferedInputStream(object hostContext)
{
//NOTE: by default, the request stream is always in buffered mode.
//return base.UseBufferedInputStream(hostContext);
return false;
}
}
config.Services.Replace(typeof(IHostBufferPolicySelector), new CustomBufferPolicySelector());
Run Code Online (Sandbox Code Playgroud)
仅供参考...上述策略选择器目前仅适用于Web Host.如果您想在SelfHost中进行类似的测试,请执行以下操作:
//NOTE: by default, the transfer mode is TransferMode.Buffered
config.TransferMode = System.ServiceModel.TransferMode.StreamedRequest;
Run Code Online (Sandbox Code Playgroud)
在上面帖子的更新B之后:
你可以修改你的处理程序如下:
public class LoggingHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Content != null)
{
string requestContent = await request.Content.ReadAsStringAsync();
}
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
if (response.Content != null)
{
string responseContent = await response.Content.ReadAsStringAsync();
}
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8017 次 |
最近记录: |