HttpServer 上的第二个请求 returns 503 服务不可用
Second request on HttpServer returns 503 Service Unavailable
我有以下设置:
1) 用于 API 测试的基础 class
public class BaseApiTest
{
private static readonly Uri BaseUri = new Uri("http://localhost");
private static HttpServer _server;
internal BaseApiTest()
{
var config = new HttpConfiguration
{
IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
WebApiConfig.Register(config);
_server = new HttpServer(config);
}
~BaseApiTest()
{
_server.Dispose();
}
protected static HttpResponseMessage GetHttpResponseMessageFrom(HttpMethod method, string relativeUri)
{
using (var client = new HttpMessageInvoker(_server))
{
var absoluteUri = new Uri(BaseUri, relativeUri);
var message = new HttpRequestMessage(method, absoluteUri);
var response = client.SendAsync(message, CancellationToken.None);
return response.Result;
}
}
2) 我要测试的每个控制器的 class 扩展:
[TestClass]
public class ChemicalApiTest : BaseApiTest
{
private const string ControllerRoutePrefix = "/api/customers/316";
[TestMethod]
public void SomeTest() {
// Act
var response =
GetHttpResponseMessageFrom(HttpMethod.Get, ControllerRoutePrefix + "/suppliers");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); // this is OK
response =
GetHttpResponseMessageFrom(HttpMethod.Get, ControllerRoutePrefix + "/suppliers");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); // This fails with 503
}
}
所以我猜 http 服务器只响应第一个查询。为什么会这样,如何修复它,我怎么知道的(在文档中的任何地方都看不到)
编辑
原来问题出在实例化客户端HttpMessageInvoker
两次。如果我像下面的代码片段那样重构 BasiApiTest
class,它就可以正常工作。但是,我仍然对我的问题感兴趣。
public class BaseApiTest
{
private static readonly Uri BaseUri = new Uri("http://localhost");
private static HttpMessageInvoker _client;
internal BaseApiTest()
{
var config = new HttpConfiguration
{
IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
WebApiConfig.Register(config);
var server = new HttpServer(config);
_client = new HttpMessageInvoker(server);
}
~BaseApiTest()
{
_client.Dispose();
}
protected static HttpResponseMessage GetHttpResponseMessageFrom(HttpMethod method, string relativeUri)
{
var absoluteUri = new Uri(BaseUri, relativeUri);
var message = new HttpRequestMessage(method, absoluteUri);
var response = _client.SendAsync(message, CancellationToken.None);
return response.Result;
}
}
原来 HttpMessageInvoker
class 有 2 个构造函数:
HttpMessageInvoker(HttpMessageHandler);
HttpMessageInvoker(HttpMessageHandler, Boolean);
第一个链接到具有 true
值的第二个,因此在我的例子中调用 new HttpMessageInvoker(server)
相当于 new HttpMessageInvoker(server, true)
并且根据规范,布尔参数是 指示此实例是否负责处理处理程序的值。
我觉得不自然的是为什么
- 默认行为是处理所提供的依赖项。
- 没有记录默认行为。
不过,第一个问题是个人看法,而第二个问题仍然可以回答这个话题的完整性。
我有以下设置:
1) 用于 API 测试的基础 class
public class BaseApiTest
{
private static readonly Uri BaseUri = new Uri("http://localhost");
private static HttpServer _server;
internal BaseApiTest()
{
var config = new HttpConfiguration
{
IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
WebApiConfig.Register(config);
_server = new HttpServer(config);
}
~BaseApiTest()
{
_server.Dispose();
}
protected static HttpResponseMessage GetHttpResponseMessageFrom(HttpMethod method, string relativeUri)
{
using (var client = new HttpMessageInvoker(_server))
{
var absoluteUri = new Uri(BaseUri, relativeUri);
var message = new HttpRequestMessage(method, absoluteUri);
var response = client.SendAsync(message, CancellationToken.None);
return response.Result;
}
}
2) 我要测试的每个控制器的 class 扩展:
[TestClass]
public class ChemicalApiTest : BaseApiTest
{
private const string ControllerRoutePrefix = "/api/customers/316";
[TestMethod]
public void SomeTest() {
// Act
var response =
GetHttpResponseMessageFrom(HttpMethod.Get, ControllerRoutePrefix + "/suppliers");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); // this is OK
response =
GetHttpResponseMessageFrom(HttpMethod.Get, ControllerRoutePrefix + "/suppliers");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); // This fails with 503
}
}
所以我猜 http 服务器只响应第一个查询。为什么会这样,如何修复它,我怎么知道的(在文档中的任何地方都看不到)
编辑
原来问题出在实例化客户端HttpMessageInvoker
两次。如果我像下面的代码片段那样重构 BasiApiTest
class,它就可以正常工作。但是,我仍然对我的问题感兴趣。
public class BaseApiTest
{
private static readonly Uri BaseUri = new Uri("http://localhost");
private static HttpMessageInvoker _client;
internal BaseApiTest()
{
var config = new HttpConfiguration
{
IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
WebApiConfig.Register(config);
var server = new HttpServer(config);
_client = new HttpMessageInvoker(server);
}
~BaseApiTest()
{
_client.Dispose();
}
protected static HttpResponseMessage GetHttpResponseMessageFrom(HttpMethod method, string relativeUri)
{
var absoluteUri = new Uri(BaseUri, relativeUri);
var message = new HttpRequestMessage(method, absoluteUri);
var response = _client.SendAsync(message, CancellationToken.None);
return response.Result;
}
}
原来 HttpMessageInvoker
class 有 2 个构造函数:
HttpMessageInvoker(HttpMessageHandler);
HttpMessageInvoker(HttpMessageHandler, Boolean);
第一个链接到具有 true
值的第二个,因此在我的例子中调用 new HttpMessageInvoker(server)
相当于 new HttpMessageInvoker(server, true)
并且根据规范,布尔参数是 指示此实例是否负责处理处理程序的值。
我觉得不自然的是为什么
- 默认行为是处理所提供的依赖项。
- 没有记录默认行为。
不过,第一个问题是个人看法,而第二个问题仍然可以回答这个话题的完整性。