使用Json.NET反序列化多个json字符串的最快方法

本文关键字:字符串 方法 json Json NET 反序列化 使用 | 更新日期: 2023-09-27 17:53:27

随着时间的推移,我将检索多个json数据块,并使用Json.NET对它们进行反序列化。我已经创建了镜像每个不同数据块结构的对象,但是当接收到每个块时,我将无法检测类型。

我希望避免尝试对每个类型进行反序列化,捕捉失败(当抛出异常时),然后转到下一个类型。这样做显然会影响性能。

是否有一种快速有效的方法来确定json消息的结构并对其进行反序列化?使用(JObject)JsonConvert.DeserializeObject(...)的唯一方法是钻入结构检查是否存在某些子结构,然后使用JsonConvert.DeserializeObject<T>(...)吗?似乎反序列化对象两次是低效的。

使用Json.NET反序列化多个json字符串的最快方法

您说过反复试验反序列化"显然对性能不利"。你测量过这个吗?反序列化器是否需要很长时间才能确定它的类型是错误的?它可能不太优雅,但可能不那么昂贵。

根据您的测量,您可能能够对JSON数据的开头进行部分字符串比较,并分支到正确的类型,并使用试错作为回退。

然而,您可能会发现,如果您尝试按最可能出现的类型进行反序列化,那么您可能会发现它足够快而无需进行额外的比较。

我没有进行广泛的测试,但类似这样的东西应该可以达到目的:

object MyDeserialize(string s) {
    using (var jr = new JsonTextReader(new StringReader(s)))
    {
        if (jr.Read() && jr.TokenType == JsonToken.StartObject) {
            while (jr.Read() && jr.TokenType == JsonToken.PropertyName) {
                switch ((string)jr.Value)
                {
                    case "MagicKey1": return JsonConvert.DeserializeObject<MagicType1>(s);
                    case "MagicKey2": return JsonConvert.DeserializeObject<MagicType2>(s);
                }
                jr.Skip();
            }
            if (jr.TokenType != JsonToken.EndObject)
                throw new ArgumentException("Expected end object");
            throw new ArgumentException("Couldn't determine object type");
        }
        else
            throw new ArgumentException("Expected start object");
    }
}
void Main() {
    var s = "{ '"MagicKey1'": [], '"b'": '"asdaasd'", '"c'": { '"a'": 5 } }";
    MyDeserialize(s);
}

我有这样的印象,甚至在我发布这个问题之前,没有明显更优雅的方法来处理这种情况。我决定做双重反序列化。我不认为这是理想的,但我想还没有更好/更干净的方法。

谢谢你的回答

您是否可以控制这两个端点?如果是这样,为什么不简单地"改变"响应来告诉您使用哪个模型呢?

SomeObjectModel|{SomeObjectModelProperty:'Value',AnotherProperty:'Value2'}

您拆分并确定"SomeObjectModel"是要反序列化其余部分的类型。