C# HttpClient 在补丁请求中返回 415 Unsupported media type

Posted

技术标签:

【中文标题】C# HttpClient 在补丁请求中返回 415 Unsupported media type【英文标题】:C# HttpClient returns 415 Unsupported media type on Patch request 【发布时间】:2020-07-30 03:03:59 【问题描述】:

我们有一个 .netcore 3.1 ApiController,其端点监听 PATCH 请求,并定义了一个用于集成/API 测试的测试服务器。

使用 Postman 发送的 PATCH 请求可以正常工作,但通过 XUnit 测试中的 HttpClient 发送的请求失败并显示 415 Unsupported media type。

邮递员补丁请求: 除了 Bearer 令牌和 Content-Type:“application/json”

在测试中,我们使用 WebApplicationFactory 和它的 factory.CreateClient() 用于我们的 HttpClient。

这应该不是 Json 序列化的问题,因为我通过调试器查看了内容,并且它似乎被序列化得很好。

此外,我们的 POST 方法使用完全相同的代码完全开箱即用(将“PATCH”替换为“POST”等)

期待一些建议。另外,如果您需要更多信息,请告诉我。非常感谢。

控制器:

[HttpPatch("id")]
public async Task<ActionResult<Unit>> Edit(Edit.Command request)

     return await Mediator.Send(request);

命令:

public class Command : IRequest

      public string Id  get; set; 

      public JsonPatchDocument<ObjectDTO> PatchDocument  get; set; 

测试:

[InlineData(/* inline data goes here */)]
public async void TestEdit_Ok(/* required parameters for the test */)

    var request = new HttpRequestMessage(new HttpMethod("PATCH"), url));
    request.Headers.Add("Authorization", "Bearer " + token);

    /* create patch document logic goes here */

    var command = new Command()
    
          Id = target,
          PatchDocument = patchDocument,
    ;

    _testHelper.AddJsonContent(request, command);

    // Act
    var response = await _client.SendAsync(request);

    // Assert
    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

其中帮助方法AddJsonContent定义为:

public void AddJsonContent(HttpRequestMessage request, object content)

      request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
      string serializedContent = JsonConvert.SerializeObject(content);
      request.Content = new StringContent(serializedContent, Encoding.UTF8, "application/json");

【问题讨论】:

如何配置WebApplicationFactory?你使用Startup 吗?它有什么作用? WebApplicationFactory 可能未配置为默认处理 PATCH 您没有指定服务器接受的 Content-Type。使用 Post 和 Patch,您应该指定从客户端发送到服务器的请求的媒体类型。您只是指定了客户对响应的期望的接受。我认为默认情况下邮递员正在发送应用程序/json。但是请尝试以与添加 Accept 添加 Content-Type 相同的方式以编程方式执行此操作并让我知道 【参考方案1】:

问题在 Asp.Net Core 5.0 中得到确认 (我确认的问题——我和主题启动器有同样的问题)

当将 xUnit 与 WebApplicationFactory 和 factory.CreateClient() 用于 HttpClient 时,PATCH 方法返回“415 Unsupported Media Type”状态。

不同组合的所有可能尝试都会导致 415 状态。

但是,Swagger 和 Postman 等其他方法与 PATCH 方法配合得很好。

只有 xUnit(或 WebApplicationFactory)PATCH 方法失败。

最后,为了进行测试,我们使用 POST 方法解决了问题,其中包含 /with-partial-update 作为路由部分。

This bug is reported to aspnetcore repository

【讨论】:

确认在哪里?是否有指向 Github 问题的链接? XUnit 对 HTTP 一无所知。 WebApplicationFactory 不是 XUnit 的一部分,它是一个用于集成测试以伪造 Web 服务器的 ASP.NET Core 类。 Swagger 和 Postman 与此无关,它们是调用真实服务器的客户端。 如果更改客户端会导致 ASP.NET 出现问题。这不是xUnit的问题吗?您没有链接到任何可靠的来源。 @TanveerBadar WebApplicationFactory 是一个用于fake a web server for integration testing 的 ASP.NET Core 类。那里可能存在错误,或者可能只是配置不正确。 @Panagiotis Kanavos,我确认了这个问题——我和主题启动者有同样的问题。我还将“使用 xUnit WebApplicationFactory”更改为“使用带有 WebApplicationFactory 的 xUnit”。请告知在哪里报告此问题? ASP.NET Core's Github repo。如果您搜索单词 WebApplicationFactory,您会看到有针对 HttpMethod.GetHttpMethod.Delete 的测试,但搜索 WebApplicationFactory PATCH 不会返回任何结果。这可能从未测试过。实际的完整异常文本将很有用。您只使用 PATCH 还是 Json Patch? Json Patch 需要 Json.NET,所以可能测试 Startup 丢失了 services.AddNewtonsoftJson() 或者测试服务器没有接收到它

以上是关于C# HttpClient 在补丁请求中返回 415 Unsupported media type的主要内容,如果未能解决你的问题,请参考以下文章

C#通过HttpClient请求第三方接口并实例化返回

C#通过HttpClient请求第三方接口并实例化返回

第二次调用 C# HttpClient 错误请求

c# Httpclient 请求在 Windows 10 上工作正常返回 403 在 Windows 7 上被禁止(相同的代码)

HTTPClient 返回 400 Bad Request 但 Postman 在 C# 中返回 201

带有自定义标头的 C# HttpClient POST 请求发送不正确的 Content-Type 标头字段