【问题标题】:Json .net. Select converter based on message fieldsjson .net。根据消息字段选择转换器
【发布时间】:2016-01-30 23:11:51
【问题描述】:

我可能有一个奇怪的用例,如果我的问题可以通过其他方式解决,我也会非常感激。

我有一个应用程序,它侦听传入事件(json 消息)并根据消息类型调用一些代码。它看起来像这样:

_queue.Subscribe(message =>
{
    var obj = JsonConvert.DeserializeObject<T>(message, _serializationSettings);

    lock (this)
    {
        var type = obj.GetType();
        typeof(IEventStorage)
              .GetMethod(nameof(IEventStorage.ProcessEvent))
              .MakeGenericMethod(type)
              .Invoke(EventsStorage, new[] { obj });
    }

    return true;
});

这里我将传入的消息反序列化为我的应用数据类型,然后基于此类型调用ProcessEvent 方法,其签名如下所示:

void ProcessEvent<TEvent>(TEvent dto) where TEvent : IEvent;

一切都很好,直到我需要修改我的数据类型,所以现在我必须使用自定义转换器来读取传入的 json。现在,我在 DeserializeObject 中遇到了一个问题,因为 Newtonsoft json 无法理解使用转换器进行反序列化的必要性。在我的消息中,我有 $type 成员,我可以使用它来选择正确的转换器进行反序列化,但我不明白如何在转换器或合约解析器中指定它。

如果有任何帮助,我将不胜感激。

【问题讨论】:

    标签: c# json serialization json.net


    【解决方案1】:

    有一个Deserialize&lt;&gt;() 的重载,它接受JsonConverters 的集合。每个JsonConverter 都有一个方法CanConvert。因此Deserialize&lt;&gt;() 方法将检查您提供的转换器并使用CanConvert 的第一个转换器

    您可以创建一个在CanConvert()ReadJson() 中返回true 的Converter,它会检查消息并决定反序列化策略(可能使用您已经创建的其他类)

    【讨论】:

    • 好吧,这看起来不是很漂亮,但是很有效!非常感谢!
    • 不客气。您能否详细说明为什么您认为这不是一个干净的解决方案?
    • 这个解决方案对我来说的问题是,如果有一天我想收到不需要特定转换器的常规消息,我无论如何都需要修改这个,因为我不能根据JSON的字段选择反序列化策略(ofc我可以自己实现,但不是通用的解决方案)
    • 啊,现在我明白了,你是对的。在这种情况下,您可以将JsonConverterAttribute 应用于您的基类,您提供的转换器将检查 json 内容以确定要反序列化到哪个具体类。然后JsonConvert.DeserializeObject&lt;T&gt;() 将自动使用你的转换器,只有当T 继承自你的基类。
    • 您的解决方案看起来不错,但所有问题都开始了,因为我无法使用 DeserializeObject 的通用版本,因为我不知道传入消息的真实类型(这就是我使用 $type 属性的原因。) .我没有在我的问题中准确描述这部分(我提到了JsonConvert.DeserializeObject&lt;T&gt;(message, _serializationSettings);,但它没有&lt;T&gt; 部分,所以转换器必须自己猜测类型。之后我可以构造基于反序列化对象的GetType 的泛型方法)。当然是我的错
    猜你喜欢
    • 2018-12-13
    • 2015-03-22
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    相关资源
    最近更新 更多