ServiceStack JSON 序列化程序:如何全局更改默认序列化程序? [英] ServiceStack JSON serializer: How can I change the default serializer globally?

查看:99
本文介绍了ServiceStack JSON 序列化程序:如何全局更改默认序列化程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个案例,ServiceStack JSON 序列化程序无法反序列化,而 Newtonsoft 的 JSON.NET 设法做到了这一点.我还没有找到用 JSON.NET 替换默认序列化程序的明确方法,因此它是全局的,适用于所有类.

I have a case where the ServiceStack JSON serializer fails to deserialize, and where Newtonsoft's JSON.NET manages to do so. I have not found a clear-cut way to replace the default serializer with JSON.NET, so its global and for all classes.

JsConfig<T>.SerializeFn 我想是可行的,但它是针对每个类的,我想要全局的所有类.

JsConfig<T>.SerializeFn I guess works, but it is per class, and I want for all classes, globally.

我该怎么做?

背景

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

I am using the ServiceStack.Messaging.Redis and Redis as an MQ solution. We use this approach to sending messages:

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);
}

和接收消息,标准的东西:

and for receiving message, standard stuff:

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

简单来说,我有一个请求类,它包含一个 公共对象 Result {get;set;},并且此属性在 ServiceStack 中反序列化为 Dictionary,而不是正确的 Type.

Simplified, I have a Request class that contains a public object Result {get; set;}, and this property is deserialized in ServiceStack as a Dictionary<string, object>, and not to the correct Type.

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

I am well aware of the recommendation to use strongly typed object, but my problem is we are not actually dealing with clean DTOs for external communication, but internal communication of internal objects, relying heavily on polymorphism and it legacy code, we are not creating new stuff right now.

所以,在某些情况下,我们有对象"属性,并且无法使用 ServiceStack 反序列化它.类型信息在那里,所以我认为它可以工作,但它没有(为了清楚起见,我已经删除了下面的命名空间):

So, in some cases, we have the "object" properties, and it doesn't work to deserialize it with ServiceStack. The Type info is there, so I assumed it would work, but it didn't (I have removed namespaces below for clarity):

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(请注意,为了清晰起见,我删除了一些属性):

This is the ssGetTextMessageTemplate (please note I removed some properties for clarity):

Result 属性没有正确反序列化,如上所示.

The Result prop was not deserialized correctly, as can be seen above.

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

When using JSON.NET, the serialized JSON is:

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

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

and after deserializing, it works as expected:

所以,我想在上面的例子中尝试使用 JSON.NET 序列化程序.

So, I'd like to try the JSON.NET serializer in the case above instead.

推荐答案

ServiceStack.Redis 对 ServiceStack.Text 的对象序列化有一个硬依赖,它不支持全局替换以使用替代的 JSON Serailizer.

ServiceStack.Redis has a hard dependency on ServiceStack.Text for its object Serialization, it doesn't support global substitution to use an alternative JSON Serailizer.

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

One workaround for sending arbitrary payloads in messages is to send a serialized JSON in a string Result property, which you could use JSON.NET to de/serialize.

另一种可能的解决方法是使用 FromObjectDictionary 反射实用程序 将对象字典转换回类型化的 DTO,例如:

Another potential workaround is using the FromObjectDictionary Reflection Utils to convert the Object Dictionary back into the typed DTO, e.g:

var result = objDictionary.FromObjectDictionary(theResultType);

这篇关于ServiceStack JSON 序列化程序:如何全局更改默认序列化程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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