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

时间:2011-04-28 19:57:31

标签: c# json.net

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

我想避免为每种类型尝试反序列化,捕获失败(抛出异常时)并继续下一种类型。这样做显然不利于表现。

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

4 个答案:

答案 0 :(得分:0)

你说过反复试验反序列化“显然会对性能造成不利影响。”你测量过这个吗?解串器需要很长时间才能确定它的类型错误吗?它可能不够优雅,但可能不那么贵。

根据您的测量结果,您可以对JSON数据的开头进行部分字符串比较,并将其分支到正确的类型,并将试错作为后备。

但是,您可能会发现,如果您尝试按最有可能发生的类型进行反序列化,那么您可以快速找到 ,而无需进行额外的比较。

答案 1 :(得分:0)

我没有对此进行过广泛的测试,但是这样的事情可以解决这个问题:

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

答案 2 :(得分:0)

在我发布问题之前,我的印象是,没有一种明显更优雅的方式来处理这种情况。我决定进行双重反序列化。我不认为这是理想的,但我想还没有更好/更清洁的方法。

感谢您的回答。

答案 3 :(得分:-1)

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

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

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