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

时间:2013-01-11 17:36:32

标签: json serialization 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;
            }
        }

ServiceStack可以实现吗?

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

"__type" : "TestProject.Model.FlightItem, TestProject"

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

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

1 个答案:

答案 0 :(得分:6)

首先,Interfaces or abstract types in DTOs are a bad idea

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

为了避免这些黑客攻击,并使其在所有JSON序列化程序中同样运行良好,最好将多态类型“扁平化”为单个“平面”DTO,然后通过线路发送。一旦你回到C#,你就可以使用代码将它投射到理想的类型中。

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