我可以用来更有效地解析这个JSON的任何属性或转换器?

时间:2017-03-07 14:56:49

标签: json.net

我从网络服务电话中获取数据。 XML中的响应如下所示:

{
...other properties,
"Witness":
[
    {"Witness":
        {
            "SomeProperty":"SomeValue",
            "Other":"whatever"
        }
    }
]
}

当我使用Newtonsoft序列化对象时,我得到了这个(我将对象存储为数据库中的Json字符串):

 public class ResponseDto
{
   public virtual List<Witness> Witnesses { get; set; }
}

POCO我想将json反序列化为:

var dto = JsonConvert.DeserializeObject<ResponsetDto>(json);

当我使用此方法时,除了Witnesses列表为null之外,其他所有内容都会反序列化而不会出现问题:

var dto = JsonConvert.DeserializeObject<ResponseDto>(json);
dto.Witnesses = new List<Witness>();

var o = JObject.Parse(json);
var token = o["Witness"];
foreach (var child in token.Children())
{
    var innerWitness = child["Witness"];
    var witness = innerWitness.ToObject<Witness>();
    dto.Witnesses.Add(witness);
}

return dto;

如果我执行以下操作,我可以让它工作(但我想知道是否有一个属性或其他我能做的工作):

[JsonExtensionData]
    private IDictionary<string, JToken> _additionalData;

[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
    //Witness is odd due to the structure of the response (Witness has an array of Witness)
    var o = _additionalData["Witness"];

    if (o != null)
    {
        Witnesses = new List<Witness>();
        foreach (var child in o.Children())
        {
            var innerWitness = child["Witness"];
            var witness = innerWitness.ToObject<Witness>();
            Witnesses.Add(witness);
        }
    }
}

public ResponseDto()
{
    _additionalData = new Dictionary<string, JToken>();
}

修改

我已经浏览过Newtonsoft网站上的文档,但我没有看到任何突出的内容。我看过(并试过)转换器,但我没有看到一个允许我按照自己的意愿行事的例子。

进一步修改

我已经能够通过以下方式获得我需要的东西(基于Newtonsoft网站上的示例),但我仍然想知道是否有更好/更简单的方法来做到这一点(我觉得我我错过了什么):

{{1}}

1 个答案:

答案 0 :(得分:1)

我不确定我可以用来更有效地解析此JSON的任何属性或转换器是什么意思?如果遇到性能问题,请参阅Eric Lippert的this article,哪些州使用分析器或其他分析工具在开始调查替代方案之前根据经验确定瓶颈所在。

话虽如此,您当前使用int i; var checkedButton = groupBox1.Controls .OfType<RadioButton>() .FirstOrDefault(rb => rb.Checked); if (int.TryParse(checkedButton.Tag.ToString(), out i)) { // here's your value } 临时缓存见证列表可能并不理想,因为在反序列化完成后您没有清除字典,导致持续多余的内存使用和可能出现的问题稍后序列化private IDictionary<string, JToken> _additionalData;

相反,您可以将ItemConverter应用于ResponseDto属性以处理额外的嵌套级别:

Witnesses

由于文章11 Ways to Improve JSON Performance & Usage中提供的建议,我使用public class ResponseDto { [JsonProperty("Witness", ItemConverterType=typeof(WitnessConverter))] public virtual List<Witness> Witnesses { get; set; } } class WitnessConverter : JsonConverter { public override bool CanConvert(Type objectType) { throw new NotImplementedException(string.Format("To avoid infinite recursion, {0} must be applied statically through attributes, not added at run time in serialization settings.", this)); } class WitnessDto { [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Serialize)] public Witness Witness { get; set; } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; var dto = serializer.Deserialize<WitnessDto>(reader); return dto.Witness; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { serializer.Serialize(writer, new WitnessDto { Witness = (Witness)value }); } } public class Witness { public string SomeProperty { get; set; } public string Other { get; set; } } 而不是加载到WitnessDto

  

如果可能,请确保您有一个与JSON匹配的类   你正在使用的结构。将通用JSON解析为JSON.net   使用FastJson的JObject或泛型字典比(或〜20%)慢   将数据读入定义的类类型。这可能是因为a   使用通用的Json.NET的JObject跟踪更多的元数据,   JArray,JValue对象。

但是,您应该对自己进行描述以确认。