随着时间的推移,我将检索多个json数据块,并使用Json.NET对它们进行反序列化。我已经创建了镜像每个不同数据块结构的对象,但是当接收到每个块时,我将无法检测类型。
我希望避免尝试对每个类型进行反序列化,捕捉失败(当抛出异常时),然后转到下一个类型。这样做显然会影响性能。
是否有一种快速有效的方法来确定json消息的结构并对其进行反序列化?使用(JObject)JsonConvert.DeserializeObject(...)
的唯一方法是钻入结构检查是否存在某些子结构,然后使用JsonConvert.DeserializeObject<T>(...)
吗?似乎反序列化对象两次是低效的。
您说过反复试验反序列化"显然对性能不利"。你测量过这个吗?反序列化器是否需要很长时间才能确定它的类型是错误的?它可能不太优雅,但可能不那么昂贵。
根据您的测量,您可能能够对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"是要反序列化其余部分的类型。