JsonPatchDocument <T>parm имеет значение null при входе в API с использованием клиента flurl - PullRequest
1 голос
/ 01 апреля 2020

Я использую Flurl для вызова моего. net ядра 3.1 API, но параметр JsonPatchDocument при входе в API не имеет значения. Я могу вызвать тот же API с помощью HttpClient, и он работает нормально, но я пытаюсь придерживаться flurl, поскольку все остальные вызовы API get / put / delete все работают с использованием 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();
    }
}

1 Ответ

1 голос
/ 01 апреля 2020

Когда вы используете такие методы, как 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>();
...