问题描述
我遇到一种情况,即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
(请注意,为清楚起见,我删除了一些属性):
如上所示,结果道具未正确反序列化。
使用JSON.NET时,序列化的JSON为:
{
"$type": "GetTextMessageTemplate,"_Type": 4,"Result": {
"$type": "System.Collections.Generic.List`1[[TextMessageTemplate,AlfaCommons]],System.Private.CoreLib","$values": [{
"$type": "TextMessageTemplate,}
]
}
}
反序列化后,它可以按预期工作:
因此,我想改用上述情况下的JSON.NET序列化器。
解决方法
ServiceStack.Redis的对象序列化对ServiceStack.Text有着严格的依赖性,它不支持使用替代的JSON Serailizer进行全局替换。
一种用于在消息中发送任意有效载荷的解决方法是在string Result
属性中发送序列化的JSON,您可以使用JSON.NET对其进行反序列化。
另一个可能的解决方法是使用FromObjectDictionary Reflection Utils将对象字典转换回类型化的DTO,例如:
var result = objDictionary.FromObjectDictionary(theResultType);