2015-09-28 69 views
1

對於C#而言,我相當陌生,至少在涉及到這樣的事情時,所以對於我擁有的少量代碼表示歉意。將JSON數據添加到泛型集合

我有一個名爲Project.cs的類,需要用來保存從第三方API獲取的數據對象。

這裏是類:

//Project.cs

public sealed class Project 
{ 
    public String Id { get; set; } 
    public String Title { get; set; } 
    public String Url { get; set; } 
} 

,你看到下面的方法,應該接受來自第三方API的數據(JSON)。

此API返回JSON格式的項目列表。

幸運的是我只需要從API(Id,Title和URL)中選擇一些屬性。

不幸的是,我不知道如何從JSON中選擇這些特定的屬性,並將它們轉換爲Project類型的集合。

這是我到目前爲止。我知道它很稀疏。

//ProjectSearch.cs

public IEnumerable<Project> GetProjects(String catId) 
{ 
    //Get the data from the API 
    WebRequest request = WebRequest.Create("http://research.a.edu/api/Catalogs('123')"); 
    request.ContentType = "application/json; charset=utf-8"; 
    WebResponse response = request.GetResponse(); 

    //put each object found in the API into a Project object   
    var project = new Project(); 

} 

所以,現在,我卡住了。我不知道如何從API中獲取所有對象,並將它們放入Project類型的集合中。我需要一個循環嗎?或者還有另一種類型的做法?從API

樣品JSON:

{"odata.metadata":"http://research.a.edu/api/Catalogs/ 
$metadata#Catalogs /@Element", "odata.id":"http://research.a.edu/api/Catalogs 
('123')", 
"Id":"12345", "ParentID":"xxxx","Name":"Test1","Created":"1/1/2015","Modified":"2/1/2015","Deleted","0","URL":"http://yoursite/1", 
('123')", 
"Id":"7897", "ParentID":"xxxx","Name":"Test2","Created":"4/1/2015","Modified":"7/1/2015","Deleted","1","URL":"http://yoursite/2", 
('123')", 
"Id":"65335", "ParentID":"xxxx","Name":"Test3","Created":"7/1/2015","Modified":"9/1/2015","Deleted","0","URL":"http://yoursite/3" 
} 

我迷路了。

如果有人能告訴我,我會很感激。

謝謝!

+1

什麼是JSON數據是什麼樣子? –

+2

您是否使用過JSON解串器的Google? – Gebb

+1

將JSON解析爲一個表示完整數據或解析爲動態的類,然後複製所需的數據? – crashmstr

回答

1

我有兩個實用功能,我只是爲了這個目的(一個用於GET和另一個用於POST)。它將泛型用於返回類型,因此可以「隨處」使用。

public static T RetrieveContent<T>(string url) 
    { 
     if (String.IsNullOrWhiteSpace(url)) 
      throw new ArgumentNullException("url"); 

     T returnValue = default(T); 

     try 
     { 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
      request.Method = "GET"; 
      request.ContentType = "application/x-www-form-urlencoded"; 
      request.Accept = "application/json; charset=utf-8"; 
      using (WebResponse response = request.GetResponse()) 
      { 
       if (response != null) 
       { 
        using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
        { 
         var serializer = new JsonSerializer(); 
         var jsonTextReader = new JsonTextReader(reader); 
         returnValue = serializer.Deserialize<T>(jsonTextReader); 
        } 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      string errMsg = String.Format("UtilitiesBL:RetrieveContent<T>(url). There was an error retrieving content from URL: {0}.", url); 
      throw new Exception(errMsg, e); 
     } 

     return returnValue; 

    } 

    public static T RetrieveContentPost<T>(string url, string postData) 
    { 
     if (String.IsNullOrWhiteSpace(url)) 
      throw new ArgumentNullException("url"); 

     T returnValue = default(T); 


     try 
     { 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
      byte[] contentBytes = Encoding.UTF8.GetBytes(postData); 
      request.Method = "POST"; 
      request.ContentType = "application/x-www-form-urlencoded"; 
      request.ContentLength = contentBytes.Length; 
      request.Accept = "application/json; charset=utf-8"; 

      // Get the request stream. 
      using(Stream dataStream = request.GetRequestStream()) 
      { 
       // Write the data to the request stream. 
       dataStream.Write(contentBytes, 0, contentBytes.Length); 
      } 
      using (WebResponse response = request.GetResponse()) 
      { 
       if (response != null) 
       { 
        using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
        { 
         var serializer = new JsonSerializer(); 
         var jsonTextReader = new JsonTextReader(reader); 
         returnValue = serializer.Deserialize<T>(jsonTextReader); 
        } 

       } 
      } 
     } 
     catch (Exception e) 
     { 
      string errMsg = String.Format("UtilitiesBL:RetrieveContentPost(url, postData). There was an error retrieving content from URL: {0}.", url); 
      throw new Exception(errMsg, e); 
     } 

     return returnValue; 

    } 

運用的問題你的樣品,你的代碼應該是這樣的:

public IEnumerable<Project> GetProjects(String catId) 
{ 
    string url = String.Format("http://research.a.edu/api/Catalogs('{0}')", catId); 
    return RetrieveContent<List<Project>>(url); 
} 
+0

謝謝!這是很多消化!如果我的JSON包含大量我不需要的數據,這將如何工作?我需要挑選出所有的對象,但每個對象只需要一些屬性。 – SkyeBoniwell

+0

我的榮幸。 'serializer.Deserialize (jsonTextReader)'只會映射您的類中存在的屬性並忽略其他屬性。你想讓我擴展的代碼有哪些部分? –

+0

謝謝。那麼我只需將其複製並粘貼到我的公共IEnumerable GetProjects(String catId)方法中? – SkyeBoniwell

3

你應該檢查最流行的JSON庫.NET:Newtonsoft JSON

的使用是非常簡單的。這個例子取自網站:

string json = @"{ 
    'Name': 'Bad Boys', 
    'ReleaseDate': '1995-4-7T00:00:00', 
    'Genres': [ 
    'Action', 
    'Comedy' 
    ] 
}"; 

Movie m = JsonConvert.DeserializeObject<Movie>(json); 

string name = m.Name; 
+0

謝謝,這是如何工作的?如果JSON中有超過1部電影怎麼辦?你需要通過JSON循環,然後添加到電影類?謝謝! – SkyeBoniwell

+1

陣列也是可以接受的。如果您不想使用序列化方法,則還可以手動解析JSON並使用LINQ to JSON來提取數據。 –

+0

所以這隻適用於一個對象在同一時間?如果JSON包含3部電影,我必須執行Movie m = JsonConvert ... 3次?謝謝 – SkyeBoniwell