相关问题:Web API ApiController PUT 和 POST 方法间歇性接收空参数 https://stackoverflow.com/questions/16091024/web-api-apicontroller-put-and-post-methods-receive-null-parameters-intermittentl
背景
在对现有 Web API 项目进行负载测试时,我注意到由于发布到操作时参数为空而导致出现许多空引用异常。
原因似乎是在开发环境中运行时注册了一个自定义消息处理程序来记录请求。删除此处理程序可以解决该问题。
据我所知,在 Web API 中我只能读取请求正文一次,并且读取它总是会导致我的参数为空,因为模型绑定无法发生。因此,我使用 ReadAsStringAsync() 方法和ContinueWith 来读取正文。看起来这在大约 0.2% 的请求中表现得很奇怪(在使用 Apache Bench 进行本地调试期间)。
Code
在最基本的层面上,我有以下几点:
Model
public class User
{
public string Name { get; set; }
}
API控制器
public class UsersController : ApiController
{
[HttpPost]
public void Foo(User user)
{
if (user == null)
{
throw new NullReferenceException();
}
}
}
消息处理程序
public class TestMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Content.ReadAsStringAsync().ContinueWith((task) =>
{
/* do stuff with task.Result */
});
return base.SendAsync(request, cancellationToken);
}
}
...在应用程序启动期间注册
GlobalConfiguration.Configuration.MessageHandlers.Add(new TestMessageHandler());
我正在使用 WebAPI 4.0.30506.0,这是发布时的最新版本。该项目中的所有其他 MS 软件包也都运行最新版本(下面链接的演示项目现已更新以反映这一点)。
Testing
最初的测试是使用Loadster http://www.loadsterperformance.com/在带有 .NET 4.0.30319 的 Server 2008 R2 上针对负载平衡的 IIS 7.5 设置运行。我使用 Apache Bench 在带有 .NET 4.5.50709 的 Windows 7 上的 IIS 7.5 上本地复制此内容。
ab -n 500 -c 25 -p testdata.post -T "application/json" http://localhost/ModelBindingFail/api/users/foo
其中 testdata.post 包含
{ "Name":"James" }
通过此测试,我发现 500 个请求中大约有 1 个失败,所以约为 0.2%。
下一步...
我已经把我的演示项目放在GitHub https://github.com/jamesantrobus/WebAPI-ModelBindingError如果您想亲自尝试,除了我上面发布的内容之外,它是一个标准的空 Web API 项目。
也很乐意尝试任何建议或发布更多信息。谢谢!