繁体   English   中英

从 Minimal API 切换到 MVC API 后,PostAsync 上的 HttpClient 400 错误请求到端点

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM