пятница, 4 октября 2013 г.

ServiceStack десериализация inherited объектов

Есть абстрактный класс Item и выведенный из него DressItem
public abstract class Item
{
   public int ItemId {get; set;}

   public string Name {get; set;}
}  

public class DressItem : Item
{
}  
Класс Item сделан абстрактным, для того, чтобы ServiceStack умел сериализовать Item с указанием типа, т .е. если у нас есть конструкция:
Item item=new DressItem(){ItemId=1,Name="Пальто"};
то при сериализации в ServiceStack данная конструкция преобразуется в json:
{"__type": "MyNameSpace.DressItem, MyAssembly","ItemId":1,"Name":"Пальто"}
и при десериализации из такого json в Item у нас создастся DressItem. Например, если сделаем сервис редактирования Items
public class ItemRequest
{
  public Item Item {get; set;}
}

public class ItemEditService : Service
{
  public object Put(ItemRequest request)
  {
    DataContext.UpdateItem(request.Item);
    return true;
  }
}
То при вызове метода Put с вышеприведеным json у нас в request.Item окажется объект типа DressItem. Но вот что, интересно, если json немного изменить, сделав его таким:
{"ItemId":1, "__type": "MyNameSpace.DressItem, MyAssembly", "Name":"Пальто"}
т. е. просто поставив ItemId вперед, то в request.Item мы получим null! Получается, при передаче данных сервису "__type" всегда должен идти первым, иначе десериализация не сработает. А ведь это не всегда возможно, ведь мы не можем знать, каким образом будут вести себя сериализаторы объектов... Довольно странное поведение сервисстэка, возможно это ошибка.