Pin*_*ong 5 c# .net-core asp.net-core asp.net-core-webapi
我在使一个API控制器调用同一项目中的另一个API控制器时遇到问题。
具体来说,集成项目能够调用生产项目中的控制器,并且该控制器将再次调用同一项目中的虚拟控制器,但是第一个控制器因内部服务器错误而失败。
但是,第一个控制器可以调用google.com。
请注意,当通过控制台或Windows服务托管生产项目时,它可以工作。仅在集成项目中的测试运行时才会发生。
生产项目是一个ASP.NET CORE Web API项目v2.1,集成测试项目是通过xUnit v2.1,请按照以下步骤进行操作
https://docs.microsoft.com/zh-cn/aspnet/core/test/integration-tests?view=aspnetcore-2.2
与xUnit的集成项目如下:
public class RetryPolicyTests: IClassFixture<WebApplicationFactory<Startup>>
{
private readonly WebApplicationFactory<Startup> _factory;
public RetryPolicyTests(WebApplicationFactory<Startup> factory)
{
_factory = factory;
}
[Theory]
[InlineData("http://localhost:1234/api/v1/Book/")]
public async Task Test(string url)
{
// Arrange
var client = _factory.CreateClient();
// Act
var body = "{}";
using (var content = new StringContent(body, Encoding.UTF8, "application/json"))
{
var response = await client.PostAsync(url, content);
// Assert
response.EnsureSuccessStatusCode(); //Failed here with internal server error
Assert.Equal(StatusCodes.Status200OK,
(int) (response.StatusCode));
}
}
}
Run Code Online (Sandbox Code Playgroud)
BookController
[ApiVersion("1")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class BookController : ControllerBase
{
private readonly ILog _logger;
private readonly IConfiguration _configuration;
private IHttpClientFactory _httpClientFactory;
public BookController(ILog logger , IConfiguration configuration, IHttpClientFactory httpClientFactory)
{
_logger = logger;
_configuration = configuration;
_httpClientFactory = httpClientFactory;
}
[HttpPost]
public async Task<ActionResult> Post()
{
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
string body = reader.ReadToEnd();
var url = "http://localhost:1234/api/v1/Author/"
using (var content = new StringContent(body, Encoding.UTF8, "application/json"))
{
var _httpClient = _httpClientFactory.CreateClient();
var s = _httpClient.GetAsync("http://google.com").Result; //works here
var response = await _httpClient.PostAsync(url, content); //internal server error
var statusCode = response.StatusCode;
return StatusCode((int)statusCode);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
AuthorController
[ApiVersion("1")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class AuthorController : ControllerBase
{
ILog _logger;
public AuthorController(ILog logger)
{
_logger = logger;
}
[HttpPost]
public void Post()
{
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
var body = reader.ReadToEnd();
}
}
Run Code Online (Sandbox Code Playgroud)
如果集成测试直接在Author控制器上命中,则它将起作用。
错误:
Result StackTrace:
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at IntegrationTests.xUnit.RetryPolicy.RetryPolicyTests.Test(String url) in C:\IntegrationTests.xUnit\RetryPolicy\RetryPolicyTests.cs:line 46
--- End of stack trace from previous location where exception was thrown ---
Result Message: System.Net.Http.HttpRequestException : Response status code does not indicate success: 500 (Internal Server Error).
Run Code Online (Sandbox Code Playgroud)
更新资料
请注意,在集成测试命中第一个控制器之后,而命中第二个控制器之前,我尝试通过外部工具(例如Postman或Fiddler)将相同的数据发送到第一个控制器。但是,并非所有工具都可用于外部工具,这与将其托管在控制台或Windows服务上不同(在这种情况下,所有控制者都可以处理请求)。
https://github.com/aspnet/AspNetCore/issues/5132
更新资料
我升级到2.2,问题仍然存在
更新资料
System.Net.Http.HttpRequestException: No connection could be made because the target machine actively refused it ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result()
at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.get_Result()
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Controllers.BookController.Post() in C:\src\Controllers\BookController.cs:line 84} System.Exception {System.Net.Http.HttpRequestException}
InnerException {System.Net.Sockets.SocketException (10061): No connection could be made because the target machine actively refused it
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)} System.Exception {System.Net.Sockets.SocketException}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
374 次 |
| 最近记录: |