随着时间的推移,我将检索多个json数据块,并使用Json.NET对它们进行反序列化。我创建的对象镜像了每个不同数据块的结构,但是当收到每个块时,我将无法检测到该类型。
我想避免为每种类型尝试反序列化,捕获失败(抛出异常时)并继续下一种类型。这样做显然不利于表现。
是否有一种快速有效的方法来确定json消息的结构并对其进行反序列化?使用(JObject)JsonConvert.DeserializeObject(...)
的唯一方法是钻入结构以检查是否存在某些子项,然后使用JsonConvert.DeserializeObject<T>(...)
?似乎对对象进行两次反序列化效率很低。
答案 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”是要将其余部分反序列化的类型。