JsonPatchDocument<T> parm 在使用 flurl 客户端输入 API 时为空



我正在使用Flurl调用我的.net core 3.1 API,但JsonPatchDocument parm在输入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>();

最新更新