猿问

获取ServiceStack以保留类型信息

获取ServiceStack以保留类型信息

我使用ServiceStack将一些对象序列化和反序列化为JSON。考虑这个例子:


public class Container

{

    public Animal Animal { get; set; }

}


public class Animal

{

}


public class Dog : Animal

{

    public void Speak() { Console.WriteLine("Woof!"); }

}


var container = new Container { Animal = new Dog() };

var json = JsonSerializer.SerializeToString(container);

var container2 = JsonSerializer.DeserializeFromString<Container>(json);


((Dog)container.Animal).Speak(); //Works

((Dog)container2.Animal).Speak(); //InvalidCastException

最后一行抛出一个InvalidCastException,因为Properties字段实例化为动物类型,而不是狗类型。有什么方法可以告诉ServiceStack保留这个特定实例属于Dog类型的信息吗?


拉莫斯之舞
浏览 403回答 3
3回答

哆啦的时光机

DTO中的继承是个坏主意-DTO的继承应该尽可能自我描述,并且通过使用继承客户端实际上不知道服务最终返回了什么。这就是DTO类在大多数基于标准的序列化器中无法正确反/序列化的原因。在DTO中使用接口没有很好的理由(在Poco模型上使用接口的理由也很少),使用接口来减少应用程序代码中的耦合是一种非常流行的习惯,而DTO中的应用程序代码正被轻率地泄漏到DTO中。但是跨进程边界,接口只会增加耦合(只在代码中减少),因为使用者不知道要反序列化到哪种具体类型,因此它必须发出特定于序列化的实现提示,即现在将C#关注点嵌入到线路上(因此现在甚至C#名称空间也将中断序列化),并且现在限制您的响应供特定的序列化程序使用。在线路上泄露C#关注点违反了支持互操作性的服务的核心目标之一。由于JSON规范中没有“type info”的概念,为了使继承在JSON序列化程序中工作,他们需要发出专有扩展到JSON线格式要包含此类型信息-现在将JSON负载耦合到特定的JSON序列化器实现中。ServiceStack的JsonSeriizer将此类型信息存储在_型属性,并且由于它会大大增加有效负载,因此只会为需要它的类型发出此类型的信息,即Interfaces晚飞object类型或abstract上课。这么说的话,解决办法就是改变Animal要么是界面或者摘要类时,建议不要在DTO中使用继承。
随时随地看视频慕课网APP
我要回答