2011-11-24 78 views
3

我使用JSON.Net嘗試反序列化來自SurveyGizmo的一些調查響應。 下面是我在讀數據的快照:JSON.Net - 反序列化對象格式

{"result_ok":true, 
"total_count":"44", 
"page":1, 
"total_pages":1, 
"results_per_page":50, 
"data":[ 
     {"id":"1", 
     "contact_id":"", 
     "status":"Complete", 
     "is_test_data":"0", 
     "datesubmitted":"2011-11-13 22:26:53", 
     "[question(59)]":"11\/12\/2011", 
     "[question(60)]":"06:15 pm", 
     "[question(62)]":"72", 
     "[question(63)]":"One", 
     "[question(69), option(10196)]":"10", 

我設置一個類就datesubmitted,但我不知道如何設置類反序列化的問題,因爲量問題會改變嗎?如果它存在,我也需要捕捉選項。

我使用此代碼使用JSON.NET反序列化功能:

Dim responses As Responses = JsonConvert.DeserializeObject(Of Responses)(fcontents) 

類:

Public Class Responses 
    Public Property result_OK As Boolean 

    Public Property total_count As Integer 

    Public Property page As Integer 

    Public Property total_pages As Integer 

    Public Property results_per_page As Integer 

    Public Overridable Property data As List(Of surveyresponse) 
End Class 

Public Class SurveyResponse 
    Public Property id As Integer 

    Public Property status As String 

    Public Property datesubmitted As Date 
End Class 

回答

2

這種伎倆來支持完全瘋狂的映射是使用JsonConverter並完全取代(我對C#表示歉意,但我不擅長VB語法):

class Program 
{ 
    static void Main(string[] args) 
    { 
     var result = JsonConvert.DeserializeObject<Responses>(TestData); 
    } 

    const string TestData = @"{""result_ok"":true, 
""total_count"":""44"", 
""page"":1, 
""total_pages"":1, 
""results_per_page"":50, 
""data"":[ 
    {""id"":""1"", 
    ""contact_id"":"""", 
    ""status"":""Complete"", 
    ""is_test_data"":""0"", 
    ""datesubmitted"":""2011-11-13 22:26:53"", 
    ""[question(59)]"":""11\/12\/2011"", 
    ""[question(60)]"":""06:15 pm"", 
    ""[question(62)]"":""72"", 
    ""[question(63)]"":""One"", 
    ""[question(69), option(10196)]"":""10"", 
}]}"; 
} 

[JsonObject] 
class Responses 
{ 
    public bool result_ok { get; set; } 
    public string total_count { get; set; } 
    public int page { get; set; } 
    public int total_pages { get; set; } 
    public int results_per_page { get; set; } 
    public SurveyResponse[] Data { get; set; } 
} 

[JsonObject] 
// Here is the magic: When you see this type, use this class to read it. 
// If you want, you can also define the JsonConverter by adding it to 
// a JsonSerializer, and parsing with that. 
[JsonConverter(typeof(DataItemConverter))] 
class SurveyResponse 
{ 
    public string id { get; set; } 
    public string contact_id { get; set; } 
    public string status { get; set; } 
    public string is_test_data { get; set; } 
    public DateTime datesubmitted { get; set; } 
    public Dictionary<int, string> questions { get; set; } 
} 

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

    public override bool CanRead 
    { 
     get { return true; } 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var value = (SurveyResponse)existingValue; 
     if (value == null) 
     { 
      value = new SurveyResponse(); 
      value.questions = new Dictionary<int, string>() 
     } 

     // Skip opening { 
     reader.Read(); 

     while (reader.TokenType == JsonToken.PropertyName) 
     { 
      var name = reader.Value.ToString(); 
      reader.Read(); 

       // Here is where you do your magic 
      if (name.StartsWith("[question(")) 
      { 
       int index = int.Parse(name.Substring(10, name.IndexOf(')') - 10)); 
       value.questions[index] = serializer.Deserialize<string>(reader); 
      } 
      else 
      { 
       var property = typeof(SurveyResponse).GetProperty(name); 
       property.SetValue(value, serializer.Deserialize(reader, property.PropertyType), null); 
      } 

      // Skip the , or } if we are at the end 
      reader.Read(); 
     } 

     return value; 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

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

現在顯然還有很多事情要做,才能讓這個功能非常強大,但是這給了你如何去做的基礎知識。還有更輕巧的替代品,如果你只需要更改屬性名稱(或者JsonPropertyAttribute或壓倒一切的DefaultContractResolver.ResolvePropertyName(),但是這給你完全的控制。

+0

西蒙, 我很欣賞的努力,你把那個答覆! 我有點嚇倒最初的回答是,我希望這會很好,很簡單!迄今爲止,除了具有選項的問題例如「[問題(31),選項(10019)]」:「39.99」外,值得注意的是,問題(31)可能有多個選項響應 所以我認爲我需要開始捕獲question_id,option_id和value,但我不認爲我可以用字典來做到這一點? – Tom

+0

我想我已經排序我很快就會發布我的更改 – Tom

+0

是的,這只是爲了讓你知道如何覆蓋屬性名稱 - >對象更新過程,我不想猜測什麼option()意思:) –