ServiceStack JSON序列化程序:如何全局更改默认序列化程序?

问题描述

我遇到一种情况,即ServiceStack JSON序列化程序无法反序列化,而Newtonsoft的JSON.NET设法做到这一点。我还没有找到一种将JSON.NET替换为认序列化器的明确方法,因此它是全局的,适用于所有类。

JsConfig<T>.Serializefn我想是可行的,但这是针对每个班级的,我希望在全球范围内针对所有班级。

我该怎么做?

背景

我正在使用ServiceStack.Messaging.Redis和Redis作为MQ解决方案。我们使用这种方法来发送消息:

using (var mqClient = MqClientFactory.Instance.CreateMessageQueueClient())
{

    var uniqueCallbackQ = "mq:c1" + ":" + Guid.NewGuid().ToString("N");
    var clientMsg = new Message<TRequest>(request)
    {
        ReplyTo = uniqueCallbackQ
    };

    mqClient.Publish(clientMsg);
    //Blocks thread on client until reply message is received
    responseMessage = mqClient.Get<TResponse>(uniqueCallbackQ,timeout);
}

以及用于接收消息的标准内容

redisMqServer.RegisterHandler<TheRequest>(base.ExecuteMessage);

简化,我有一个包含public object Result {get; set;}的Request类,并且此属性在ServiceStack中反序列化为Dictionary<string,object>,而不是正确的Type。

我很清楚使用强类型对象的建议,但是我的问题是我们实际上不是在处理用于外部通信的干净的DTO,而是内部对象的内部通信,在很大程度上依赖于多态性及其遗留代码,我们现在不创建新内容

因此,在某些情况下,我们具有“对象”属性,并且无法通过ServiceStack反序列化它。类型信息在那里,所以我认为它可以工作,但是没有(为了清楚起见,我在下面删除名称空间):

string ssjson = ServiceStack.Text.JsonSerializer.SerializetoString(getTextMessageTemplateObject);

// above produces: 

{
    "_Type": "Deviation","Result": [{
            "__type": "TextMessageTemplate,AlfaCommons","_Message": "test","_Type": "Deviation",}
    ],"Success": true,}

// And then,deserialize the json above:

GetTextMessageTemplate ssGetTextMessageTemplate = ServiceStack.Text.JsonSerializer.DeserializefromString< 
GetTextMessageTemplate>(ssjson);

这是ssGetTextMessageTemplate(请注意,为清楚起见,我删除了一些属性):

enter image description here

如上所示,结果道具未正确反序列化。

使用JSON.NET时,序列化的JSON为:

{
    "$type": "GetTextMessageTemplate,"_Type": 4,"Result": {
        "$type": "System.Collections.Generic.List`1[[TextMessageTemplate,AlfaCommons]],System.Private.CoreLib","$values": [{
                "$type": "TextMessageTemplate,}
        ]
    }
}

反序列化后,它可以按预期工作:

enter image description here

因此,我想改用上述情况下的JSON.NET序列化器。

解决方法

ServiceStack.Redis的对象序列化对ServiceStack.Text有着严格的依赖性,它不支持使用替代的JSON Serailizer进行全局替换。

一种用于在消息中发送任意有效载荷的解决方法是在string Result属性中发送序列化的JSON,您可以使用JSON.NET对其进行反序列化。

另一个可能的解决方法是使用FromObjectDictionary Reflection Utils将对象字典转换回类型化的DTO,例如:

var result = objDictionary.FromObjectDictionary(theResultType);