Будни кросс-платформенного Web от Microsoft
ASP NET Core базируется на платформе NET Core, которая, в свою очередь является кросс-платформенной, на данный момент доступна версия 2.0.х (у меня NET Core работает, что под Windows 7, что под Linux Mint 18). Сам ASP NET Core включает в себя Entity Framework, Json Converter (от Newtonsoft), IoC и т.п. Сегодня пойдет речь о работе с Json, точнее о том, что я в итоге получил.
Приколы с POST и PUT и десериализацией из Json
Предположим у нас есть два проекта в солюшене, пусть они называются ClickPlatform.Dto и ClickPlatform.Mvc. В первом у нас объявлены классы Dto - объектов, а вот втором - Web API с набором контроллеров с методами (Get, Post, Put и Delete для обработки одноименных HTTP-методов и действий).
У нас есть следующий класс Dto:
public class Listing
{
public Listing() { }
public Listing(Guid id, string name, AdShortInfo[] linkedAd = null, string status = null, TotalStatistics stats = null)
{
Id = id;
Name = name;
LinkedAd = linkedAd;
Status = status;
Stats = stats;
}
public Guid Id { get; set; }
public string Name { get; set; }
public AdShortInfo[] LinkedAd { get; set; }
public string Status { get; set; }
public TotalStatistics Stats { get; set; }
}
Понятно, что для получения объекта и коллекции объектов используем Get-методы, с сериализацией тут все ок, все хорошо работает. и мы получаем либо коллекцию объектов, либо отдельный объект по id. Чудеса начинаются при использовании методов Post и Put внутри следующего контроллера
[Produces("application/json")]
[Route("api/[controller]")]
public class ListingController : Controller
{
.// ...
[HttpPost]
public void Post([FromBody] Dto.Internal.Listing listing)
{
_listingManager.Create(listing);
}
[HttpPut("{id}")]
public void Put([FromRoute]Guid id, [FromBody]Dto.Internal.Listing listing)
{
_listingManager.Update(id, listing);
}
// ...
}
Пробуем дернуть Post при этом устанавливаем content-type=application/json и charset=utf-8. и передаем следующий json: {"id":"","status":"active","name":"Evil_One","linkedAd":[], "stats":""}
Точка останова показывает нам, что наш объект - null.
Если мы поставим object, то получим следующее:
[HttpPost]
public void Post([FromBody] /*Dto.Internal.Listing*/ object listing)
{
//_listingManager.Create(listing);
}
Теперь объект в теле определился, получается, что Json не может десериализовать объект в Dto.Internal.Listing. Почему же так происходит? Все дело оказывается в том, что если для value type значение в Json не задано, то считается, что там null, а null нельзя использовать для value-типов, поэтому приходится везде ставить Nullable<T>. В вышеприведенном коде поменяет свойство Guid Id {get; set;} на Guid? Id {get; set;}. И теперь смело можем передавать запрос со значением "" в качестве Guid
При этом сам Newtonsoft.Json не соизволил проинформировать о том, что он не может десериализовать тип. Что ж вот такая она десериализация объектов в Asp NET.
Послесловие (послевкусие)
Попробовал я ASP NET Core и не могу сказать, что это супер платформа, не могу сказать, что это именно то, что нужно для разработки. В ней вроде как бы все есть, но что-то в ней не так. Многие вещи кажутся странными: как например молчаливая обработка ошибок, подтягивание Nuget пакетов для самых очевидных вещей вроде System.Data и многое другое. Если сюда добавить работу только на VS17 (на мой взгляд, худшая студия начиная с 2003, даже 2010 была лучше).
ASP NET Core базируется на платформе NET Core, которая, в свою очередь является кросс-платформенной, на данный момент доступна версия 2.0.х (у меня NET Core работает, что под Windows 7, что под Linux Mint 18). Сам ASP NET Core включает в себя Entity Framework, Json Converter (от Newtonsoft), IoC и т.п. Сегодня пойдет речь о работе с Json, точнее о том, что я в итоге получил.
Приколы с POST и PUT и десериализацией из Json
Предположим у нас есть два проекта в солюшене, пусть они называются ClickPlatform.Dto и ClickPlatform.Mvc. В первом у нас объявлены классы Dto - объектов, а вот втором - Web API с набором контроллеров с методами (Get, Post, Put и Delete для обработки одноименных HTTP-методов и действий).
У нас есть следующий класс Dto:
public class Listing
{
public Listing() { }
public Listing(Guid id, string name, AdShortInfo[] linkedAd = null, string status = null, TotalStatistics stats = null)
{
Id = id;
Name = name;
LinkedAd = linkedAd;
Status = status;
Stats = stats;
}
public Guid Id { get; set; }
public string Name { get; set; }
public AdShortInfo[] LinkedAd { get; set; }
public string Status { get; set; }
public TotalStatistics Stats { get; set; }
}
Понятно, что для получения объекта и коллекции объектов используем Get-методы, с сериализацией тут все ок, все хорошо работает. и мы получаем либо коллекцию объектов, либо отдельный объект по id. Чудеса начинаются при использовании методов Post и Put внутри следующего контроллера
[Produces("application/json")]
[Route("api/[controller]")]
public class ListingController : Controller
{
.// ...
[HttpPost]
public void Post([FromBody] Dto.Internal.Listing listing)
{
_listingManager.Create(listing);
}
[HttpPut("{id}")]
public void Put([FromRoute]Guid id, [FromBody]Dto.Internal.Listing listing)
{
_listingManager.Update(id, listing);
}
// ...
}
Пробуем дернуть Post при этом устанавливаем content-type=application/json и charset=utf-8. и передаем следующий json: {"id":"","status":"active","name":"Evil_One","linkedAd":[], "stats":""}
Точка останова показывает нам, что наш объект - null.
Если мы поставим object, то получим следующее:
[HttpPost]
public void Post([FromBody] /*Dto.Internal.Listing*/ object listing)
{
//_listingManager.Create(listing);
}
Теперь объект в теле определился, получается, что Json не может десериализовать объект в Dto.Internal.Listing. Почему же так происходит? Все дело оказывается в том, что если для value type значение в Json не задано, то считается, что там null, а null нельзя использовать для value-типов, поэтому приходится везде ставить Nullable<T>. В вышеприведенном коде поменяет свойство Guid Id {get; set;} на Guid? Id {get; set;}. И теперь смело можем передавать запрос со значением "" в качестве Guid
При этом сам Newtonsoft.Json не соизволил проинформировать о том, что он не может десериализовать тип. Что ж вот такая она десериализация объектов в Asp NET.
Послесловие (послевкусие)
Попробовал я ASP NET Core и не могу сказать, что это супер платформа, не могу сказать, что это именно то, что нужно для разработки. В ней вроде как бы все есть, но что-то в ней не так. Многие вещи кажутся странными: как например молчаливая обработка ошибок, подтягивание Nuget пакетов для самых очевидных вещей вроде System.Data и многое другое. Если сюда добавить работу только на VS17 (на мой взгляд, худшая студия начиная с 2003, даже 2010 была лучше).
Комментариев нет:
Отправить комментарий