2011-09-19 119 views
4

我有一个web服务返回json数据。我无法控制服务器端生成的json。反序列化json对象并将内部对象转换为字符串值?

我反序列化JSON是这样的:

JsonConvert.DeserializeObject<OuterObject>(jsonString); 

的问题是有嵌入式(有一大堆更多的嵌套内部对象)内的物体。我没有兴趣在我的应用程序中对它们进行建模。

JSON的数据是这样的:

{ 
    id : "xyz", 
    name : "Some Object", 
    properties : { 
     prop_1 : "foo", 
     prop_2 : "bar" 
    }, 
    inner_object : { 
     id : "abc$1", 
     name : "Inner Object Name", 
     .... 
     // a whole lot of stuff here 
     // with more embedded objects 
     .... 
    } 
} 

我想外部对象作为一个简单的POCO,其中内-目的通过只是一个(字符串)ID,而不是一个对象引用的模型参考。

public class Outer 
{ 
    public String Id { get; internal set; } 
    public String Name { get; internal set; } 
    public Dictionary<String,String> Properties { get; internal set; } 

    // Just keep the InnerObject Id, no real reference to an instance 
    public String InnerObjectId { get; set; } 
} 

我想我可以写一个JsonOuterObject版采用了真正的对象引用JsonInnerObject,并从那里建造我的真实OuterObject,扔掉以后,别的对象......但是这太瘸。 (我不想看到我的名字接下来在这样的提交中)

所以我现在玩弄Json.NET的IContractResolver(覆盖DefaultContractResolver),但它看起来像我在一个很长的时间骑在这里。

我错过了一些明显的Json.NET功能,在这里照顾这个吗?

或者,也许一些指针IContractResolver的哪些方法在这里很有趣?

编辑:在.NET中的POJO是一个aparently。

+0

如果你有任何控制被发送的对象,你可以删除那些不需要的属性... –

+0

好吧,就像我说的:我不:-) – toong

回答

2

一种方法是使用Newtonsoft.Json.Linq和动态类型,因为您基本上试图(或被迫)弯曲类型安全规则。

public class Outer 
    {    
     [JsonProperty(PropertyName = "id")] 
     public String Id { get; internal set; } 
     [JsonProperty(PropertyName = "name")] 
     public String Name { get; internal set; } 
     [JsonProperty(PropertyName = "properties")] 
     public Dictionary<String, String> Properties { get; internal set; } 
     [JsonProperty(PropertyName = "inner_object")] 
     public dynamic InnerObjectId { get; set; } 
    } 

    public void InnerObjectAsDynamic() 
    { 
     const string json = @"{""id"":""xyz"",""name"":""Some Object"",""properties"":{""prop_1"":""foo"",""prop_2"":""bar""},""inner_object"":{""id"":""abc$1"",""name"":""Inner Object Name""}}"; 
     var outer = JsonConvert.DeserializeObject<Outer>(json); 
     var innerObjectJson = outer.InnerObjectId.ToString(); 
     Console.WriteLine(innerObjectJson); 
     //{ 
     // "id": "abc$1", 
     // "name": "Inner Object Name" 
     //} 
    } 

或者,你可以定义为外:

public class Outer 
    { 
     [JsonProperty(PropertyName = "id")] 
     public String Id { get; internal set; } 
     [JsonProperty(PropertyName = "name")] 
     public String Name { get; internal set; } 
     [JsonProperty(PropertyName = "properties")] 
     public Dictionary<String, String> Properties { get; internal set; } 
     [JsonProperty(PropertyName = "inner_object")] 
     public Newtonsoft.Json.Linq.JObject InnerObjectId { get; set; } 
    } 

这是干净了一点给我。祝你好运。

3

为外部类型创建自定义JsonConverter允许在反序列化对象时有很大的灵活性。

这是相当多的工作,但它可以是值得的努力。特别是如果您无法控制返回的JSON对象,并且想要在客户端应用程序中对返回的数据进行不同的建模。

的JsonConverter实现的肉重写ReadJson方法

public override object ReadJson(JsonReader reader, 
           Type objectType, 
           object existingValue, 
           JsonSerializer serializer) 

的JsonReader是您的数据的标记化流。实现可能是这样的:

public override object ReadJson(JsonReader reader, 
           Type objectType, 
           object existingValue, 
           JsonSerializer serializer) 
{ 
    var outer = new Outer() 

    while (reader.TokenType != JsonToken.EndObject) 
    { 
     if (reader.TokenType == JsonToken.PropertyName) 
     { 
      var propertyName = reader.Value.ToString(); 
      reader.Read(); 

      switch (propertyName) 
      { 
       case "id": 
        outer.Id = serializer.Deserialize<String>(reader); 
        break; 
       case "id": 
        outer.Properties = serializer.Deserialize<Dictionary<String,String>>(reader); 
        break; 
       case "inner_object" 
        var inner = serializer.Deserialize<Inner>(reader); 
        outer.InnerObjectId = inner.Id; 
        break; 
       [...more cases...] 
       default: 
        serializer.Deserialize<object>(reader); 
        break; 
       } 
       reader.Read(); // consume tokens in reader 
      } 
     } else { 
      // throw exception ? 
     } 
    } 

    return outer; 
} 

您可以用JsonConverterAttribute注释您的外部对象或转换器通过一个很长的(超载)反序列化(字符串JSON,则params JsonConverter []转换器)的JsonConverter类的方法

相关问题