使用ServiceStack.Text序列化多态集合

Joa*_*rks 4 serialization json servicestack

我们正在从Json.NET切换到ServiceStack.Text,我遇到了多态集合序列化的问题.

在JSON.NET中,我曾经创建一个自定义的JsonCreationConverter并重写Create()方法来选择我想要创建的类型 - 如下所述:

http://dotnetbyexample.blogspot.co.uk/2012/02/json-deserialization-with-jsonnet-class.html

有问题的集合是List<ItemBase>可以包含FlightItemCarHireItem对象.

这是我对JSON.NET的Create()方法的版本:

protected override ItemBase Create(Type objectType, JObject jsonObject)
        {
            var itemType = jsonObject["Type"].ToString();
            switch (itemType)
            {
                case "flight":
                    return new FlightItem();
                case "carhire":
                    return new CarHireItem();
                default: 
                    return null;
            }
        }
Run Code Online (Sandbox Code Playgroud)

这可能与ServiceStack有关吗?

ServiceStack中的多态集合的序列化和反序列化工作正常,但它将对象类型附加到JSON输出,例如

"__type" : "TestProject.Model.FlightItem, TestProject"
Run Code Online (Sandbox Code Playgroud)

这意味着我需要在发布JSON时提供类型,并且我不太热衷于在API调用中为任何人显示.NET类型.

有什么建议?如果可以用不同的方式做到这一点,你能指点我一些例子吗?

myt*_*thz 6

首先,DTO中的接口或抽象类型是个坏主意.

你现在处于一个奇怪的位置,你试图在DTO中支持多态类型,但是不想提供特定于JSON Serializer的信息?您需要定制代码来支持多态DTO的原因是因为根据有线格式无法确定应该使用哪种具体类型,因此为什么ServiceStack会为此目的发出__type属性.

为了避免这些黑客攻击,并使其在所有JSON序列化程序中都能正常工作,最好将多态类型"扁平化"为单个"平面"DTO,然后通过线路发送.一旦你回到C#,你就可以使用代码将它投射到理想的类型中.

ServiceStack确实提供了一些JsConfig<ItemBase>.RawDeserializeFn可以让你做类似事情的东西,请参阅CustomSerializerTests作为示例.还有JsConfig<ItemBase>.OnDeserializedFn可能有帮助的钩子,但它取决于是否ItemBase包含两种具体类型的完整属性列表.