[英]Calling an api using httpClient PostAsync - 400 Bad Request
[英]HttpClient 400 bad request on PostAsync to endpoint after switching from Minimal API to MVC API
我开始使用运行良好的 .NET 6 最小 api,但是我需要一些额外的功能,所以我决定切换到 MVC 风格的 api。 从那时起,当我的 WPF 应用程序尝试使用 POST 调用端点时,我收到 400 错误请求。 如果我使用 swagger 拨打电话,它可以正常工作。 但是在我的 WPF 应用程序中使用 HttpClient 会出现错误。 我已经查看了有关此错误的十几个其他问题,但似乎没有一个解决方案可以解决我的问题。
当我通过调试运行 API 和 WPF 应用程序并调试对 InsertUser 的 UserService 调用和 API 的 InsertUser 方法的开始时,API 的调试点永远不会被命中,这对我来说听起来就像 MVC 正在处理它看到的请求时它不喜欢并返回 400 错误,但我不确定为什么 PUT 请求很好而 POST 请求不是。
在我的 ASP.net 核心 program.cs 中,我添加了以下内容以启用 MVC api 使用
builder.Services.AddControllers();
app.MapControllers();
在我的 WPF 应用程序中,httpClient 通过 DI 处理并注入到用于调用端点的 UserService 类中。
InsertUser POST 方法
public async Task<bool> InsertUser(UserModel user)
{
var result = await _httpClient.PostAsync("/api/Users",
user.AsJsonContent());
return result.IsSuccessStatusCode;
}
这是使用 PUT 并且工作正常的 UpdateUser 方法
public async Task<bool> UpdateUser(UserModel user)
{
var result = await _httpClient.PutAsync("/api/Users",
user.AsJsonContent());
return result.IsSuccessStatusCode;
}
将 UserModel 转换为 StringContent 的扩展
public static StringContent AsJsonContent(this object obj)
{
string json = JsonConvert.SerializeObject(obj);
var content = new StringContent(json, Encoding.UTF8, "application/json");
//content.Headers.Remove("Content-Type");
//content.Headers.Add("Content-Type", "application/json");
//content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return content;
}
这是我的 UsersController 的精简版
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
[HttpPost]
public async Task<IActionResult> InsertUser(UserModel model)
{
_appDbContext.Users.Add(model);
var result = await _appDbContext.SaveChangesAsync();
return result > 0 ? Ok() : Problem("User was not inserted");
}
[HttpPut]
public async Task<IActionResult> UpdateUser(UserModel model)
{
if(await _appDbContext.Users.FindAsync(model.Id) is UserModel efModel)
{
_mapper.Map(model, efModel);
_appDbContext.Users.Update(efModel);
var result = await _appDbContext.SaveChangesAsync();
return result > 0 ? Ok() : Problem("User was not updated");
}
return Problem("User not found.");
}
}
这是 PostAsync 的结果
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
Date: Thu, 07 Jul 2022 14:35:53 GMT
Server: Kestrel
Transfer-Encoding: chunked
Content-Type: application/problem+json; charset=utf-8
}}
这是我的回复信息
{Method: POST, RequestUri: 'https://localhost:7159/api/Users', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
Content-Type: application/json
Content-Length: 253
}}
编辑:添加所需信息
这是坏响应的json响应
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-ac9fc01b742547b2525eef9de28ea6a0-d123c5b603ff637c-00",
"errors": {
"Token": [
"The Token field is required."
]
}
}
这是 InsertUser 的最小 api 版本
//Registered in another class
app.MapPost("/Users", InsertUser);
public async Task<bool> InsertUser(UserModel model)
{
await _appDbContext.Users.AddAsync(model);
var result = await _appDbContext.SaveChangesAsync();
return result > 0;
}
由于您将数据作为 json 内容发布,因此您必须向两个控制器操作添加 frombody 属性
public async Task<IActionResult> UpdateUser([FromBody]UserModel model)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.