获取ServiceStack保留类型信息 [英] Getting ServiceStack to retain type information

查看:239
本文介绍了获取ServiceStack保留类型信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using ServiceStack to serialize and deserialize some objects to JSON. Consider this example:

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的,因为动物字段实例化为动物类型,不是狗的类型。有什么办法,我可以告诉ServiceStack保留的信息,这个特殊的例子是狗型的?

The last line throws a InvalidCastException, because the Animal field is instantiated as an Animal type, not a Dog type. Is there any way I can tell ServiceStack to retain the information that this particular instance was of the Dog type?

推荐答案

继承中的DTO是一个坏主意 - DTO的应该是自我描述,尽可能通过继承的客户有效地不知道该服务最终返回。这就是为什么你的DTO类将无法取消/序列正确地最基于标准的串行。

Inheritance in DTOs is a bad idea - DTO's should be as self-describing as possible and by using inheritance clients effectively have no idea what the service ultimately returns. Which is why your DTO classes will fail to de/serialize properly in most 'standards-based' serializers.

有没有很好的理由具有DTO的接口(只有极少数的理由来让他们对POCO模型),它的使用接口减少耦合应用code,它正在被轻率地泄露到的DTO的货物邪教习惯。但是跨进程边界,接口只增加耦合(这只是在code减少),因为消费者不知道反序列化到所以它发出的序列化的具体实施暗示,现在嵌入C#的担忧在电线上有什么具体类型(所以现在连C#的命名空间将打破序列化),现在限制你的回应中使用由特定序列化。泄漏的C#担忧的电线违反服务,为实现互操作性的核心目标之一。

There's no good reason for having interfaces in DTO's (and very few reasons to have them on POCO models), it's a cargo cult habit of using interfaces to reduce coupling in application code that's being thoughtlessly leaked into DTOs. But across process boundaries, interfaces only adds coupling (it's only reduced in code) since the consumer has no idea what concrete type to deserialize into so it has to emit serialization-specific implementation hints that now embeds C# concerns on the wire (so now even C# namespaces will break serialization) and now constrains your response to be used by a particular serializer. Leaking C# concerns on the wire violates one of the core goal of services for enabling interoperability.

由于存在着类信息在JSON规范,没有概念,以便继承JSON序列化器工作,他们需要的发出专有扩展JSON wireformat 包括这种类型的信息 - 现在将你的JSON有效载荷到一个特定的JSON序列化实施

As there is no concept of 'type info' in the JSON spec, in order for inheritance to work in JSON Serializers they need to emit proprietary extensions to the JSON wireformat to include this type info - which now couples your JSON payload to a specific JSON serializer implementation.

ServiceStack的JsonSerializer 存储在 __类型财产,因为它可以大大这种类型的信息膨胀的有效载荷,只会发出这种类型的信息,有需要的类型,即接口,后期绑定对象类型或摘要类。

ServiceStack's JsonSerializer stores this type info in the __type property and since it can considerably bloat the payload, will only emit this type information for types that need it, i.e. Interfaces, late-bound object types or abstract classes.

随着中说,解决办法是动物来改变要么是接口摘要类,该建议但不使用继承的DTO。

With that said the solution would be to change Animal to either be an Interface or an abstract class, the recommendation however is not to use inheritance in DTOs.

这篇关于获取ServiceStack保留类型信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆