使用 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>();
我正在使用 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>();