2014-04-06 100 views
0

我不能为我的生活弄清楚如何让这个JSON反序列化成我可以在代码中使用和读取的东西。我创建了一个类,并在每个属性上使用JsonProperty来处理json名称中句号的无效使用。但我无法弄清楚如何创建根对象。带数字的属性是随机的,生活在字典中。但recsindb和recsonpage是静态名称。反序列化奇数JSON字典

{ 
    "1": { 
     "orders.orderid":"538", 
     "entity.customerid":"109", 
     "entity.entityid":"538", 
    }, 
    "2": { 
     "orders.orderid":"536", 
     "entity.customerid":"108", 
     "entity.entityid":"536", 
    }, 
    "recsindb":"2", 
    "recsonpage":"2" 
} 
+0

的可能重复的[REST API的包装设计:返回动态JSON作为JSON.NET JObject/JArray](http://stackoverflow.com/questions/22879772/rest-api-wrapper-design-returning-dynamic-json-as-json-net-jobject -jarray) –

+0

我已经标记为可能的重复问答我几天前回答。标题是不同的,但它也是你的一个可能的解决方案! –

+0

@MatíasFidemraizer这不像是另一个问题,没有什么是像其他问题那样高度动态。这是一个与属性混合的字典之间的问题。布赖恩的答案实际上完美地击中了头部。 –

回答

1

您可以使用自定义JsonConverter来处理这种情况。
定义你的数据类是这样的:

[JsonConverter(typeof(CustomConverter))] 
public class RootObject 
{ 
    public Dictionary<string, Order> Orders { get; set; } 
    public string RecsInDB { get; set; } 
    public string RecsOnPage { get; set; } 
} 

public class Order 
{ 
    [JsonProperty("orders.orderid")] 
    public string OrderID { get; set; } 

    [JsonProperty("entity.customerid")] 
    public string CustomerID { get; set; } 

    [JsonProperty("entity.entityid")] 
    public string EntityID { get; set; } 
} 

创建一个自定义的转换器来处理根对象是这样的:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JObject jo = JObject.Load(reader); 
     RootObject obj = new RootObject(); 
     obj.RecsInDB = jo["recsindb"].ToString(); 
     obj.RecsOnPage = jo["recsonpage"].ToString(); 
     obj.Orders = new Dictionary<string, Order>(); 
     foreach (JProperty prop in jo.Properties()) 
     { 
      if (prop.Name != "recsindb" && prop.Name != "recsonpage") 
      { 
       obj.Orders.Add(prop.Name, prop.Value.ToObject<Order>()); 
      } 
     } 
     return obj; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

然后你就可以反序列化这样的:

RootObject obj = JsonConvert.DeserializeObject<RootObject>(json); 

现在您可以像平常一样使用数据类。这里是一个演示:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string json = @" 
     { 
      ""1"": { 
       ""orders.orderid"":""538"", 
       ""entity.customerid"":""109"", 
       ""entity.entityid"":""538"", 
      }, 
      ""2"": { 
       ""orders.orderid"":""536"", 
       ""entity.customerid"":""108"", 
       ""entity.entityid"":""536"", 
      }, 
      ""recsindb"":""2"", 
      ""recsonpage"":""2"" 
     }"; 

     RootObject obj = JsonConvert.DeserializeObject<RootObject>(json); 

     Console.WriteLine("RecsInDB: " + obj.RecsInDB); 
     Console.WriteLine("RecsOnPage: " + obj.RecsOnPage); 
     foreach (var kvp in obj.Orders) 
     { 
      Console.WriteLine("Order #" + kvp.Key); 
      Console.WriteLine(" OrderID " + kvp.Value.OrderID); 
      Console.WriteLine(" CustomerID " + kvp.Value.CustomerID); 
      Console.WriteLine(" EntityID " + kvp.Value.EntityID); 
     } 
    } 
} 

输出:

RecsInDB: 2 
RecsOnPage: 2 
Order #1 
    OrderID 538 
    CustomerID 109 
    EntityID 538 
Order #2 
    OrderID 536 
    CustomerID 108 
    EntityID 536 
+0

工作完美,谢谢。我唯一不同的做法是让Orders成为RootObject的一个属性,我从Dictionary 继承了RootObject,并将订单添加到RootObject。 –

+0

没问题;乐意效劳。 –