2011-09-19 206 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類的方法

相關問題