asp.net-core - JsonPatchDocument<T> 调用 API 时抛出 400 错误

标签 asp.net-core restful-url json-patch

我收到“响应状态代码并不表示成功:400(错误请求)”。在我的 API 上进行 HTTP PATCH 调用时出错。当我从 API 方法中删除“[FromBody] JsonPatchDocument param”时,它会起作用。

有什么想法吗?

这是一个带有 Blazor 前端的 asp.net core 3.1 Restful api(这并不重要)....

+------------+
| Web Client |      
+------------+
public async Task<BoatDto> UpdateBoatPartialAsync(Guid clubId, Guid boatId, BoatForUpdateDto boatForUpdateDto)
{
    BoatDto boatDtoFromApi = null;

    var patchDoc = new JsonPatchDocument<BoatForUpdateDto>()
        .Replace(o => o.Name, boatForUpdateDto.Name)
        .Replace(o => o.Description, boatForUpdateDto.Description);

    var serializedPatchDoc = JsonConvert.SerializeObject(patchDoc);

    try
    {
        var _httpClient = new HttpClient();
        _httpClient.BaseAddress = new Uri(https://localhost:44383);
        _httpClient.Timeout = new TimeSpan(0, 0, 30);
        _httpClient.DefaultRequestHeaders.Clear();

        var request = new HttpRequestMessage(HttpMethod.Patch, $"clubs/{clubId.ToString()}/boats/{boatId}");
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        request.Content = new StringContent(serializedPatchDoc);
        request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json-patch+json");

        var response = await _httpClient.SendAsync(request);
        response.EnsureSuccessStatusCode();

        var content = await response.Content.ReadAsStringAsync();
        return JsonConvert.DeserializeObject<BoatDto>(content);

    }
    catch (Exception ex)
    {
        throw;
    }

    return boatDtoFromApi;
}

+-----+
| API |     
+-----+     
[AllowAnonymous]
[ApiController]
[Route("clubs/{clubId}/boats")]
public class BoatsController : ControllerBase
{
    private readonly ClubRepo _clubRepo;
    private readonly BoatRepo _boatRepo;
    private readonly IMapper _mapper;

    public BoatsController(ClubRepo clubRepo, BoatRepo boatRepo, IMapper mapper)
    {
        _clubRepo = clubRepo ?? throw new ArgumentNullException(nameof(clubRepo));
        _boatRepo = boatRepo ?? throw new ArgumentNullException(nameof(boatRepo));
        _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
    }

    [HttpPatch]
    [Route("{boatId}")]
    public ActionResult UpsertBoatPartial(Guid clubId, Guid boatId, [FromBody] JsonPatchDocument<BoatForUpdateDto> boatPatchDocDto)
    {
        return Ok(); //never gets called
    }

    //[HttpPatch]
    //[Route("{boatId}")]
    //public ActionResult Test(Guid clubId, Guid boatId)
    //{
    //    return Ok(); //will get called
    //}

}

+-----+
| DTO |     
+-----+ 
public class BoatForUpdateDto
{
    public string Name { get; set; } 
    public string Description { get; set; } 
}

public class BoatDto
{
    public Guid ClubId { get; set; }
    public Guid BoatId { get; set; } 
    public string Name { get; set; }
    public string Description { get; set; }         
}

最佳答案

成功了!我必须将以下内容添加到 API 的startup.cs 中:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddControllers(setupAction =>
    {
        setupAction.ReturnHttpNotAcceptable = true;
    })
    .AddXmlDataContractSerializerFormatters()
    .AddNewtonsoftJson(setupAction => setupAction.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver()
    );
    ...
}

关于asp.net-core - JsonPatchDocument<T> 调用 API 时抛出 400 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60962347/

相关文章:

asp.net-core - 如何在 ASP.NET 5 中生成 XML 文档文件

api - FluentValidator 和 JsonPatchDocument

json - JSON 指针中波浪号的用途

azure - 在 Azure WebJobs 中使用 NLog 进行日志记录

c# - Custom Tag Helper - 替换 html 标签

c# - ASP.NET 5 跨平台,老式 DLL 将何去何从?

java - Java HttpPost 中序列化为请求参数的 json

rest - 设计Restful API时,UNFOLLOW应该用DELETE还是POST?

ios - Twitter 获取请求不断返回代码 88 - "Rate limit exceeded"

java - 如何获取两个 REST API 响应的差异?