2012-10-23 44 views
2

在C#中使用JSON我試圖程序.NET C#代碼來讀取調用的結果campaignEmailStatsAIMAll()從mailchimp campaignEmailStatsAIMAll

這裏是JSON結果我得到的一個樣本:

{ 
    "total":3, 
    "data":{ 
     "[email protected]":[ 
     { 
      "action":"click", 
      "timestamp":"2012-10-18 20:55:52", 
      "url":"http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)", 
      "ip":"66.66.666.666" 
     }, 
     { 
      "action":"open", 
      "timestamp":"2012-10-18 20:55:52", 
      "url":null, 
      "ip":"66.66.666.666" 
     } 
     ], 
     "[email protected]":[ 
     { 
      "action":"open", 
      "timestamp":"2012-10-18 20:18:05", 
      "url":null, 
      "ip":"22.222.222.222" 
     }, 
     { 
      "action":"open", 
      "timestamp":"2012-10-18 20:18:18", 
      "url":null, 
      "ip":"22.222.222.222" 
     }, 
     { 
      "action":"click", 
      "timestamp":"2012-10-18 20:18:18", 
      "url":"http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)", 
      "ip":"22.222.222.222" 
     }, 
     { 
      "action":"click", 
      "timestamp":"2012-10-18 20:21:57", 
      "url":"http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)", 
      "ip":"22.222.222.222" 
     } 
     ], 
     "[email protected]":[ 

     ] 
    } 
} 

我遇到的問題是如何定義的C#對象接受這個JSON字符串。這些電子郵件地址被視爲JSON名稱/值對的名稱部分。我知道有對.NET的第三方包裝,但我只想把這個API(也許其他幾個上下行),並寧願代碼它自己。我希望能夠遍歷該對象以提取電子郵件地址,然後爲每個對象提供action/timestamp/url。

當我把這個JSON成json2sharp.com對象的創建者,我得到這個:

public class SomebodyCompanyCom {  
    public string action { get; set; }  
    public string timestamp { get; set; }  
    public string url { get; set; }  
    public string ip { get; set; } 
} 

public class AnotherpersonCorporationCom {  
    public string action { get; set; }  
    public string timestamp { get; set; }  
    public string url { get; set; }  
    public string ip { get; set; } 
} 

public class Data {  
    public List<SomebodyCompanyCom> [email protected] { get; set; }  
    public List<AnotherpersonCorporationCom> [email protected] { get; set; }  
    public List<object> [email protected] { get; set; } 
} 

public class RootObject {  
    public int total { get; set; }  
    public Data data { get; set; } 
} 

回答

1

就像一臺發電機只能永遠做最好的猜測。由於JSON通常是無模式的,因此您需要分析數據並找出建模的最佳方式。

你的情況,你有兩種基本類型:

  1. 由行動,時間戳,URL的各個條目和IP
  2. 整體容器總和數據

一合理的模式可能是這樣的:

public class ItemInfo {  
    public string action { get; set; }  
    public string timestamp { get; set; }  
    public string url { get; set; }  
    public string ip { get; set; } 
} 

public class ContainerType { 
    public int total; 
    public Dictionary<string, ItemInfo[]> data; 
} 

如果你使用一個體面的JSON庫利柯JSON.Net,你可以反序列化JSON字符串轉換爲ContatinerType結構如下所示:

string rawJsonString = MagicallyGetTheJsonFromAWebservice(); 
ContainerType container = JsonConvert.DeserializeObject<ContainerType>(rawJsonString); 

它可能需要一些調整,以獲得反序列化類型準確的工作,但這是最基本的想法。

編輯:樣本控制檯程序做反序列化:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Newtonsoft.Json; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static string testData = @"{ 
    'total':3, 
    'data':{ 
     '[email protected]':[ 
     { 
      'action':'click', 
      'timestamp':'2012-10-18 20:55:52', 
      'url':'http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)', 
      'ip':'66.66.666.666' 
     }, 
     { 
      'action':'open', 
      'timestamp':'2012-10-18 20:55:52', 
      'url':null, 
      'ip':'66.66.666.666' 
     } 
     ], 
     '[email protected]':[ 
     { 
      'action':'open', 
      'timestamp':'2012-10-18 20:18:05', 
      'url':null, 
      'ip':'22.222.222.222' 
     }, 
     { 
      'action':'open', 
      'timestamp':'2012-10-18 20:18:18', 
      'url':null, 
      'ip':'22.222.222.222' 
     }, 
     { 
      'action':'click', 
      'timestamp':'2012-10-18 20:18:18', 
      'url':'http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)', 
      'ip':'22.222.222.222' 
     }, 
     { 
      'action':'click', 
      'timestamp':'2012-10-18 20:21:57', 
      'url':'http:\/\/www.someurl.com?ct=t(First_Chimp_Test10_18_2012)', 
      'ip':'22.222.222.222' 
     } 
     ], 
     '[email protected]':[ 

     ] 
    } 
}"; 

     public class ItemInfo {  
      public string action { get; set; }  
      public string timestamp { get; set; }  
      public string url { get; set; }  
      public string ip { get; set; } 
     } 

     public class ContainerType { 
      public int total; 
      public Dictionary<string, ItemInfo[]> data; 
     } 
     static void Main(string[] args) 
     { 
      ContainerType container = JsonConvert.DeserializeObject<ContainerType>(testData); 
      if((container.total != 3) 
       || (container.data.Count != 3) 
       || (container.data["[email protected]"][1].action != "open") 
       || (container.data["[email protected]"][2].url != "http://www.someurl.com?ct=t(First_Chimp_Test10_18_2012)")) 
      { 
       Console.WriteLine("Failed to deserialize"); 
      } 
      else 
      { 
       Console.WriteLine("Successfully deserialized"); 
      } 

      foreach (string email in container.data.Keys) 
      { 
       Console.WriteLine(email); 
       for (int x = 0; x < container.data[email].Count(); x++) 
       { 
        Console.WriteLine("\t" + x.ToString() + ":"); 
        Console.WriteLine("\t\taction : " + container.data[email][x].action); 
        Console.WriteLine("\t\ttimestamp: " + container.data[email][x].timestamp); 
        Console.WriteLine("\t\turl  : " + container.data[email][x].url); 
        Console.WriteLine("\t\tip  : " + container.data[email][x].ip); 
       } 
      } 
     } 
    } 
} 
+0

我想你會捉襟見肘,認爲它不是一本字典 - 它在JSON表示方式是規範的方式序列化字典。無論如何,問題是如何在C#靜態類型中對數據建模,我相信這是最有效的方法。 –

+0

我有一個測試程序可以發佈。我的文章的要點是Data類不適合數據,並且他不應該爲每個條目定義多個類型。 –

+0

感謝您的示例。它的工作原理,但是...我可以通過像container.data索引訪問信息container.data [0] [1] .action(不工作),因爲在返回給我的電子郵件地址(一些... @ company.com,anothe ... @ corporation.com「)是未知的,也就是說,它們每次都會有所不同。我想找出的電子郵件地址是什麼,然後找出動作,URL等從ItemInfo。 – user1769025