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

4
我们正在从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时需要提供类型,但我不太愿意让.NET类型对API调用中的任何人可见。
有什么建议吗?如果有其他方法可以实现此功能,您能给我指些示例吗?
1个回答

6
首先,在DTO中使用接口或抽象类型是不好的
现在你处于一个奇怪的位置,你想在DTO中支持多态类型,但又不希望提供特定于JSON序列化器的信息?之所以需要定制的代码来支持多态DTO,是因为无法根据线路格式确定应使用哪种具体类型,这就是为什么ServiceStack为此目的发出__type属性的原因。
为了避免这些黑客行为,并使其在所有JSON序列化器中同样有效,你最好将多态类型“展开”为单个“平面”DTO,并将其发送到线路上。一旦回到C#中,您可以使用代码将其投影到理想的类型中。
ServiceStack确实提供了一些JsConfig<ItemBase>.RawDeserializeFn,让你做类似的事情,请参见CustomSerializerTests的示例。还有JsConfig<ItemBase>.OnDeserializedFn钩子,可能会有所帮助,但它取决于ItemBase是否包含两种具体类型的完整属性列表。

我曾经考虑过在我的WebApi中不使用多态类型。但是这不仅意味着需要为每个子类编写单独的方法,还需要为每个多态属性类的变化编写单独的方法,这是非常不实际的,因此我放弃了那个想法。 - Jens Mander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接