2015-05-22 61 views
2

我一直在遇到這樣的情況,我想將一些JSON反序列化成與JSON結構不完全匹配的類型。舉例來說,如果我有JSON是這樣的:如何用JSON.NET「扁平化」一些JSON?

"foo": { 
    "bar": { 
    "1": 10, 
    "4": 20, 
    "3": 30, 
    "2": 40, 
    "5": 50 
    }, 
} 

那我就需要這樣的事:

class Bar 
{ 
    [JsonProperty] 
    int One; 
    [JsonProperty] 
    int Two; 
    [JsonProperty] 
    int Three; 
    [JsonProperty] 
    int Four; 
    [JsonProperty] 
    int Five; 
} 

class Foo 
{ 
    [JsonProperty] 
    Bar bar; 
} 

但是,如果我想將它變成這樣呢?

class Foo 
{ 
    int[] values; 
} 

在那裏通過從每一箇中減去1並使得陣列出它的鑰匙0爲基礎的指數轉換?我怎樣才能做到這一點?

我還有很多這種custon反序列化的其他例子,但我只是爲了說明而發表另一個例子,因爲我不想要一個適合這個確切例子的解決方案,而是我可以推廣。

"foo": { 
    "bar": [ 
    { 
     // Bunch of unimportant stuff 
    }, 
    { 
     // Something about the structure of this object alerts me to the fact that this is an interesting record. 
     "baz": 12 
    }, 
    { 
     // Bunch of unimportant stuff 
    } 
    ] 
} 

而且我想這變成:

class Foo 
{ 
    int baz; 
} 

我看CustomCreationConverters的幾個例子,如this,但我無法適應那裏呈現任的解決方案以上情況。

回答

2

//這個對象的結構告訴我這是一個有趣的記錄。

我不認爲JSON對象的結構應該告訴任何關於它的「重要性」。客戶端不應發送任何不相關的信息,或者您必須在您的應用程序的某處編寫自定義代碼,從您的JSON對象中選擇相關信息。業務規則應該確定數據的重要性。將JSON視爲簡單的數據。

至於你的第一個例子,你可以處理像這樣使用CustomCreationConverters問題(如你所提到的)和LINQ to JSON:

public class Foo 
{ 
    public int[] Values { get; set; } 
} 

public class FooConverter : CustomCreationConverter<Foo> 
{ 
    public override Foo Create(Type objectType) 
    { 
     return new Foo(); 
    } 

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

     // Load JObject from stream 
     JObject jObject = JObject.Load(reader); 

     // Create target object based on JObject 
     Foo target = Create(objectType); 

     // get the properties inside 'bar' as a list of JToken objects 
     IList<JToken> results = jObject["foo"]["bar"].Children().ToList(); 

     IList<int> values = new List<int>(); 

     // deserialize the tokens into a list of int values 
     foreach (JToken result in results) 
     { 
      int val = JsonConvert.DeserializeObject<int>(result.First.ToString()); 
      values.Add(val); 
     } 

     target.Values = values.ToArray(); 

     return target; 
    } 
} 

使用方法如下:

string fooText = @"{'foo': { 
          'bar': { 
           '1': 10, 
           '4': 20, 
           '3': 30, 
           '2': 40, 
           '5': 50 
           }, 
          } 
          }"; 


Foo foo = JsonConvert.DeserializeObject<Foo>(fooText, new FooConverter()); 

你可以詳細瞭解CustomCreationConverters以及如何在JSON.NET文檔中反序列化部分JSON片段:

http://www.newtonsoft.com/json/help/html/CustomCreationConverter.htm

http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm