发布对象数组时从 Web API 接收 405 HTTP 响应 (.Net Core 5)
Receiving a 405 HTTP Response from Web API when posting an array of objects (.Net Core 5)
我在 Orange Pi 的 Linux (Debian 10) 上有一个 .Net Core 5 控制台应用程序 运行。
我正在尝试 post 一些 JSON 到 Web API(也是用 .Net Core 5 编写并托管在 Azure App Service 上)
API 有两个 HTTPPOST 端点 - 一个用于接收单个对象,另一个几乎相同的端点用于接收所述对象的数组。
当我 post 将单个对象发送到第一个端点时,我收到 201 Created 状态代码响应。但是当我 post 一个相同对象的数组时, API returns 一个 405 响应:
StatusCode: 415, ReasonPhrase: 'Unsupported Media Type', Version: 1.1,
Content: System.Net.Http.HttpConnectionResponseContent, Headers: {
Server: Microsoft-IIS/10.0 Request-Context: appId= X-Powered-By:
ASP.NET Set-Cookie:
ARRAffinity=10f4677b6e2472959a213314a4f212e32905ecb3d38e1a47aefbb00645a0d541;Path=/;HttpOnly;Secure;Domain=eball-api.azurewebsites.net
Set-Cookie:
ARRAffinitySameSite=10f4677b6e2472959a213314a4f212e32905ecb3d38e1a47aefbb00645a0d541;Path=/;HttpOnly;SameSite=None;Secure;Domain=eball-api.azurewebsites.net
Date: Sun, 28 Feb 2021 18:58:41 GMT Content-Length: 175
Content-Type: application/problem+json; charset=utf-8 }
这是我的控制台应用程序的样子:
public partial class ReadingDto
{
public int? Id { get; set; }
public DateTime? TimeReceived { get; set; }
public double? Frequency { get; set; }
public byte? FrequencyByte { get; set; }
public byte? Modulation { get; set; }
public byte? AGC1 { get; set; }
public byte? AGC2 { get; set; }
public string RawData { get; set; }
public bool? IsTest { get; set; }
public bool IsReported { get; set; }
public DateTime? TimeReported { get; set; }
}
private async Task PostReadings(List<ReadingDto> readingsDto)
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = "https://somedomain.com/api/";
string serializedObject = JsonSerializer.Serialize(readingsDto);
StringContent content = new StringContent(serializedObject);
using (var response = await httpClient.PostAsync("readings/batch", content))
{
Console.Write(response.IsSuccessStatusCode);
}
}
}
这就是 API 控制器中的操作方法:
[Route("api/[controller]")]
[ApiController]
public class ReadingsController : Controller
{
[HttpPost("batch")]
public async Task<IActionResult> PostReadings([FromBody] List<ReadingDto> readingsDto)
{
List<Reading> readings = _mapper.Map<List<Reading>>(readingsDto);
_context.Readings.AddRange(readings);
await _context.SaveChangesAsync();
return Created("GetReadings", readings);
}
}
有什么想法吗?我搜索了很多论坛,大多数建议替换这一行:
StringContent content = new StringContent(serializedObject);
有了这个
StringContent content = new StringContent(serializedObject, Encoding.UTF8, "application/json");
但是当我这样做时,我得到了这个错误:
StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content:
System.Net.Http.HttpConnectionResponseContent, Headers: {
Transfer-Encoding: chunked Server: Microsoft-IIS/10.0
Request-Context: appId= X-Powered-By: ASP.NET Set-Cookie:
ARRAffinity=10f4677b6e2472959a213314a4f212e32905ecb3d38e1a47aefbb00645a0d541;Path=/;HttpOnly;Secure;Domain=eball-api.azurewebsites.net
Set-Cookie:
ARRAffinitySameSite=10f4677b6e2472959a213314a4f212e32905ecb3d38e1a47aefbb00645a0d541;Path=/;HttpOnly;SameSite=None;Secure;Domain=eball-api.azurewebsites.net
Date: Sun, 28 Feb 2021 19:07:45 GMT Content-Type:
application/problem+json; charset=utf-8 }
我会通过使用 System.Net.Http.Formatting
包中包含的 PostAsJsonAsync
来完全避免 StringContent
:
await httpClient.PostAsJsonAsync("url", readingsDto);
此外,我建议使用 IHttpClientFactory
创建 HttpClient
。
我设法找出问题所在。客户端使用的 ReadingDto class 与 API 使用的 ReadingDto class 略有不同。客户端版本的数据类型是可为空的整数,而 API 版本是不可为空的整数。所以客户端试图 POST Id 字段中的空值,API 不喜欢。
对于浪费大家的时间,我深表歉意。不幸的是,我不能在上班时间处理这个项目,因为我当时在工作,所以我必须在下班后处理(然后只有在我儿子睡着后(晚上 10 点左右))!这就是工作到很晚很累的问题!
我在 Orange Pi 的 Linux (Debian 10) 上有一个 .Net Core 5 控制台应用程序 运行。 我正在尝试 post 一些 JSON 到 Web API(也是用 .Net Core 5 编写并托管在 Azure App Service 上) API 有两个 HTTPPOST 端点 - 一个用于接收单个对象,另一个几乎相同的端点用于接收所述对象的数组。
当我 post 将单个对象发送到第一个端点时,我收到 201 Created 状态代码响应。但是当我 post 一个相同对象的数组时, API returns 一个 405 响应:
StatusCode: 415, ReasonPhrase: 'Unsupported Media Type', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers: {
Server: Microsoft-IIS/10.0 Request-Context: appId= X-Powered-By: ASP.NET Set-Cookie: ARRAffinity=10f4677b6e2472959a213314a4f212e32905ecb3d38e1a47aefbb00645a0d541;Path=/;HttpOnly;Secure;Domain=eball-api.azurewebsites.net Set-Cookie: ARRAffinitySameSite=10f4677b6e2472959a213314a4f212e32905ecb3d38e1a47aefbb00645a0d541;Path=/;HttpOnly;SameSite=None;Secure;Domain=eball-api.azurewebsites.net Date: Sun, 28 Feb 2021 18:58:41 GMT Content-Length: 175
Content-Type: application/problem+json; charset=utf-8 }
这是我的控制台应用程序的样子:
public partial class ReadingDto
{
public int? Id { get; set; }
public DateTime? TimeReceived { get; set; }
public double? Frequency { get; set; }
public byte? FrequencyByte { get; set; }
public byte? Modulation { get; set; }
public byte? AGC1 { get; set; }
public byte? AGC2 { get; set; }
public string RawData { get; set; }
public bool? IsTest { get; set; }
public bool IsReported { get; set; }
public DateTime? TimeReported { get; set; }
}
private async Task PostReadings(List<ReadingDto> readingsDto)
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = "https://somedomain.com/api/";
string serializedObject = JsonSerializer.Serialize(readingsDto);
StringContent content = new StringContent(serializedObject);
using (var response = await httpClient.PostAsync("readings/batch", content))
{
Console.Write(response.IsSuccessStatusCode);
}
}
}
这就是 API 控制器中的操作方法:
[Route("api/[controller]")]
[ApiController]
public class ReadingsController : Controller
{
[HttpPost("batch")]
public async Task<IActionResult> PostReadings([FromBody] List<ReadingDto> readingsDto)
{
List<Reading> readings = _mapper.Map<List<Reading>>(readingsDto);
_context.Readings.AddRange(readings);
await _context.SaveChangesAsync();
return Created("GetReadings", readings);
}
}
有什么想法吗?我搜索了很多论坛,大多数建议替换这一行:
StringContent content = new StringContent(serializedObject);
有了这个
StringContent content = new StringContent(serializedObject, Encoding.UTF8, "application/json");
但是当我这样做时,我得到了这个错误:
StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers: {
Transfer-Encoding: chunked Server: Microsoft-IIS/10.0
Request-Context: appId= X-Powered-By: ASP.NET Set-Cookie: ARRAffinity=10f4677b6e2472959a213314a4f212e32905ecb3d38e1a47aefbb00645a0d541;Path=/;HttpOnly;Secure;Domain=eball-api.azurewebsites.net Set-Cookie: ARRAffinitySameSite=10f4677b6e2472959a213314a4f212e32905ecb3d38e1a47aefbb00645a0d541;Path=/;HttpOnly;SameSite=None;Secure;Domain=eball-api.azurewebsites.net Date: Sun, 28 Feb 2021 19:07:45 GMT Content-Type: application/problem+json; charset=utf-8 }
我会通过使用 System.Net.Http.Formatting
包中包含的 PostAsJsonAsync
来完全避免 StringContent
:
await httpClient.PostAsJsonAsync("url", readingsDto);
此外,我建议使用 IHttpClientFactory
创建 HttpClient
。
我设法找出问题所在。客户端使用的 ReadingDto class 与 API 使用的 ReadingDto class 略有不同。客户端版本的数据类型是可为空的整数,而 API 版本是不可为空的整数。所以客户端试图 POST Id 字段中的空值,API 不喜欢。
对于浪费大家的时间,我深表歉意。不幸的是,我不能在上班时间处理这个项目,因为我当时在工作,所以我必须在下班后处理(然后只有在我儿子睡着后(晚上 10 点左右))!这就是工作到很晚很累的问题!