使用 flurl 客户端进入 API 时 JsonPatchDocument<T> 参数为空

JsonPatchDocument<T> parm is null on entering API using a flurl client

我正在使用 Flurl 调用我的 .net core 3.1 API,但是 JsonPatchDocument 参数在进入 API 时为空。我可以用 HttpClient 调用相同的 API,它工作正常,但我试图坚持使用 flurl,因为我的另一个 get/put/delete API 调用所有工作都使用 flurl。

这是调用代码(来自 Blazor 网络客户端):

+------------+
| 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);

    var uri = $"https://localhost:44383/clubs/{clubId.ToString()}/boats/{boatId}";
    var url = uri.WithHeader("Accept", "application/json");
    var json = new StringContent(serializedPatchDoc);
    json.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json-patch+json");
    boatDtoFromApi = await url.PatchJsonAsync(json).ReceiveJson<BoatDto>();
    return boatDtoFromApi;
}   

这里是 API:

+-----+
| API |     
+-----+     
[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)
    {
        //boatPatchDocDto is null
        return Ok();
    }
}

当您使用像 PatchJsonAsync 这样的方法时,Flurl 会在后台使用 Newtonsoft.Json 为您进行序列化)。您不需要执行以下任一步骤:

var serializedPatchDoc = JsonConvert.SerializeObject(patchDoc);
...
var json = new StringContent(serializedPatchDoc);

这基本上是双重序列化,这可能解释了为什么 API 没有在后端正确解释它。直接发送 patchDoc 即可。您的大部分客户端示例都可以简化为:

boatDtoFromApi = await uri
    .WithHeader("Content-Type", "application/json-patch+json")
    .WithHeader("Accept", "application/json")
    .PatchJsonAsync(patchDoc) //edited
    .ReceiveJson<BoatDto>();