Показаны сообщения с ярлыком serialization. Показать все сообщения
Показаны сообщения с ярлыком serialization. Показать все сообщения

пятница, 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" всегда должен идти первым, иначе десериализация не сработает. А ведь это не всегда возможно, ведь мы не можем знать, каким образом будут вести себя сериализаторы объектов... Довольно странное поведение сервисстэка, возможно это ошибка.

воскресенье, 19 мая 2013 г.

ServiceStack и сериализация struct


Столкнулся с такой проблемой: при сериализации ServiceStack'ом .NET структур, вместо значений свойств в Json формате после сериализации получал название типа данных данной структуры.
 public struct Point
 {
  public int X { get; set;}
  public int Y { get; set;}
 }

 Point p = new Point (){X=10,Y=20};
 JsonSerializer.SerializeToString<Point> (p);
получал "MyNameSpace.Point" вместо "{X=10,Y=20}". В описании сериализатора ServiceStack есть заметка, что структуры сериализуются с помощью метода ToString(), но писать для каждой структуры свой сериализатор в ToString() - это чересчур. Но, к счастью, нашлось решение. Оказалось, что достаточно добавить строчку
 JsConfig<Point>.TreatValueAsRefType = true;
После чего сериализация стала работать как ожидается.