Один ключевой сценарий все еще не охвачен новыми API.
Когда я услышал о новых API-интерфейсах System.Text.Json, я был заинтригован. Я большой поклонник Newtonsoft.Json, но улучшения в Pipes в .NET Core 2.2 означают, что может появиться возможность неплохого прироста производительности.
Я был очень рад, что Microsoft решила провести исследование удобства использования своих новых API-интерфейсов, чтобы убедиться, что они не слишком сложны в использовании. Оказывается, были. Итак, в Preview 8 команда проделала кучу работ по очистке API-интерфейсов, сделав их более предсказуемыми (AKA соответствует тому, к чему люди привыкли, с Newtonsoft.Json).
Изменения велики, а новая поверхность API чиста и предсказуема. Но когда я пошел обновлять Azure DevOps Buddy до Preview 8, я столкнулся с некоторыми проблемами, связанными с ключевым сценарием.
Связывание модели в MVC / WebApi довольно раздражает, поскольку следующий код не работает, когда вы отправляете POST объект JSON в API.
public async Task<bool> SomeMethod([FromBody] SomeObject data){ }
для того, чтобы это сработало, вы должны создать объект для POST следующим образом:
var request = new { data: { property1: "test1", property2: "test2" } }; var result = $ajax.post("someurl", request);
Мне не очень нравится заставлять конечного разработчика называть объект таким образом, поэтому я часто использую вместо этого такой шаблон:
public async Task<bool> SomeMethod([FromBody] JObject data) { var model = data.ToObject<SomeObject>(); }
Насколько я могу судить (и я могу ошибаться в этом, поэтому, пожалуйста, дайте мне знать, если я прав, и я обновлю сообщение), в System.Text.Json нет эквивалента JObject. JsonDocument не имеет пустого конструктора, поэтому его нельзя использовать во время привязки модели. Я полагаю, что можно было бы создать индивидуальную подшивку модели, но усилия не окупились.
К счастью, API-интерфейсы не исключают друг друга, вы можете использовать ОБА в своем приложении, если вы добавите NuGet-пакет Microsoft.AspNetCore.Mvc.NewtonsoftJson в свой проект, а затем зарегистрируете их в Startup.cs следующим образом:
public void ConfigureServices(IServiceCollection services) { services.AddMvc() .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver()) .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNameCaseInsensitive = true);
Тогда желаемый узор продолжит работу.
Вот и все! Если найду схему получше, обязательно обновлю этот пост. Удачного кодирования!