直接在JSON中反序列化嵌套元素

时间:2013-11-21 05:30:46

标签: c# json.net deserialization

假设我有以下JSON:

{
  id: 123,
  attr: {
    info: {
      dat: [{data:1}, {data:2}]
    }
  }
}

是否可以预设整个对象但直接获取dat数组而不创建attrinfo的嵌套层次结构?

我尝试过使用(天真)

public class DataContainer {

    [JsonProperty(PropertyName = "id")]
    public int ID { get; set; }

    [JsonProperty(PropertyName = "attr.info.dat")]
    public List<dat> Data { get; set; }
}

但没有用。

另一个明显的解决方案当然是创建一个没有层次结构的单独类,解析JSON然后将所需数据复制到新对象。我目前使用这种方法,但如果可以直接解析到所需的结构,那就太好了。

2 个答案:

答案 0 :(得分:1)

试试这个

如果你想将你的Json字符串转换成一个类,请使用这个http://json2csharp.com/然后按照代码...它对我来说很好用

public class Dat
{
public int data { get; set; }
}

 public class Info
 {
  public List<Dat> dat { get; set; }
 }

public class Attr
{
 public Info info { get; set; }
}

 public class RootObject
 {
   public int id { get; set; }
  public Attr attr { get; set; }
 }



 string sValue = "{id: 123,attr: {info: {dat: [{data:1}, {data:2}]}}}";
        System.Web.Script.Serialization.JavaScriptSerializer ObjJSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        var Data = ObjJSerializer.Deserialize<RootObject>(sValue);

答案 1 :(得分:1)

快速执行此操作的方法是使用Json.Net的Linq-To-Json API。假设您的类定义如下:

public class DataContainer
{
    public int ID { get; set; }
    public List<Dat> Data { get; set; }
}

public class Dat
{
    public int Data { get; set; }
}

然后你可以将你的JSON反序列化为你的类结构:

string json = @"{
  ""id"": 123,
  ""attr"": {
    ""info"": {
      ""dat"": [{""data"":1}, {""data"":2}]
    }
  }
}";

JObject jo = JObject.Parse(json);
DataContainer container = new DataContainer();
container.ID = jo["id"].Value<int>();
container.Data = jo["attr"]["info"]["dat"].ToObject<List<Dat>>();

Console.WriteLine("id:" + container.ID);
foreach (Dat d in container.Data)
{
    Console.WriteLine(d.Data);
}

输出:

id:123
1
2

稍微强大的解决方案是将上述代码放入自定义JsonConverter,然后可以与JsonConvert.DeserializeObject()一起使用。这封装了反序列化逻辑,使主代码更加清晰。以下是转换器的代码。 (请注意,我也实现了WriteJson方法,但除非您希望将类序列化为JSON,否则不需要这样做。)

public class DataContainerConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(DataContainer));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        DataContainer container = new DataContainer();
        container.ID = jo["id"].Value<int>();
        container.Data = jo["attr"]["info"]["dat"].ToObject<List<Dat>>(serializer);
        return container;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        DataContainer container = (DataContainer)value;
        JObject jo = new JObject();
        jo.Add("id", container.ID);
        JObject attr = new JObject();
        jo.Add("attr", attr);
        JObject info = new JObject();
        attr.Add("info", info);
        JArray dat = JArray.FromObject(container.Data, serializer);
        info.Add("dat", dat);
        jo.WriteTo(writer);
    }
}

您可以使用[JsonConverter]属性修饰您的类来使用JsonConverter:

[JsonConverter(typeof(DataContainerConverter))]
public class DataContainer
{
    public int ID { get; set; }
    public List<Dat> Data { get; set; }
}

或将其实例传递给JsonConvert.DeserializeObject()

var container = JsonConvert.DeserializeObject<DataContainer>(json, new DataContainerConverter());
相关问题