2016-11-11 102 views
1

我正在通過SSIS腳本組件一個Web API JSON響應,這是回來的格式如下:反序列化JSON網絡API響應 - 嵌套對象

{ 
    "Success": true, 
    "Response": { 
    "Applications": [ 
     { 
     "App_ID": 1638486, 
     "App_Ref": "Test Example", 
     "Status": "Complete", 
     "Error_Code": null, 
     "Error_Message": null, 
     "Create_Dt": "2014-05-14 03:09:01.030 +00:00", 
     "Modify_Dt": "2014-05-14 03:10:59.757 +00:00", 
     "Client_Name": "Silver Chef", 
     "Client_Code": "SLVC01", 
     "Centrelink_Status": "Receiving_Logons" 
     }, 
     { 
     "App_ID": 1637906, 
     "App_Ref": "SME Demo", 
     "Status": "Complete", 
     "Error_Code": null, 
     "Error_Message": null, 
     "Create_Dt": "2015-10-08 03:07:26.793 +00:00", 
     "Modify_Dt": "2015-10-08 03:23:32.833 +00:00", 
     "Client_Name": "Silver Chef", 
     "Client_Code": "SLVC01", 
     "Centrelink_Status": "Receiving_Logons" 
     }, 
     { 
     "App_ID": 1585286, 
     "App_Ref": "Test", 
     "Status": "Receiving_Logons", 
     "Error_Code": null, 
     "Error_Message": null, 
     "Create_Dt": "2015-12-04 03:12:49.617 +00:00", 
     "Modify_Dt": "2015-12-04 03:12:49.617 +00:00", 
     "Client_Name": "Silver Chef", 
     "Client_Code": "SLVC01", 
     "Centrelink_Status": "Receiving_Logons" 
     } 
], 
    "Current_Dt": "2016-11-11 01:01:01.743 +00:00", 
    "Last_App_Dt": "2016-10-03 22:48:56.397 +00:00", 
    "Count": 500, 
    "Total": 1870 
    } 
} 

我已經宣佈了以下類:

 public class Application 
     { 
      public int App_ID { get; set; } 
      public string App_Ref { get; set; } 
      public string Status { get; set; } 
      public int Error_Code { get; set; } 
      public string Error_Message { get; set; } 
      public DateTime Create_Dt { get; set; } 
      public DateTime Modify_Dt { get; set; } 
      public string Client_Name { get; set; } 
      public string Client_Code { get; set; } 
      public int Centrelink_Status { get; set; } 

     } 
     public class Response 
     { 
      public List<Application> Applications { get; set; } 
      public string Current_Dt { get; set; } 
      public string Last_App_Dt { get; set; } 
      public int Count { get; set; } 
      public int Total { get; set; } 
     } 

     public class RootObject 
     { 
      public bool Success { get; set; } 
      public Response Response { get; set; } 
     } 

And this is the method that I am using to get the response. 
private RootObject GetWebServiceResult(string vAPIUrl) 
    { 

     string vAPIToken = Variables.APIToken; 

     //Create Web Request 
     HttpWebRequest apireq = (HttpWebRequest)WebRequest.Create(vAPIUrl); 
     apireq.ContentType = "application/json"; 
     apireq.Method = "POST"; 

     string jsonPostStr = "{\"Settings\": {\"API_Token\": \"" + vAPIToken + "\"}, \"Payload\": {}}"; 
     byte[] postString = Encoding.UTF8.GetBytes(jsonPostStr); 

     apireq.ContentLength = postString.Length; 

     Stream jsonStream = apireq.GetRequestStream(); 

     jsonStream.Write(postString, 0, postString.Length); 
     jsonStream.Close(); 

     // Get Web Response   
     HttpWebResponse apirsp = (HttpWebResponse)apireq.GetResponse(); 
     RootObject jsonResponse = null; 

     Stream jsonRspStream = apirsp.GetResponseStream(); 
     string apiResponseString = null; 

     using (StreamReader reader = new StreamReader(jsonRspStream)) 
     { 
      apiResponseString = reader.ReadToEnd(); 
      Console.WriteLine(apiResponseString); 
      reader.Close(); 
     } 


     JavaScriptSerializer returnJson = new JavaScriptSerializer(); 

     //var serialJsonStr = returnJson.Serialize(apiResponseString); 
     System.Windows.Forms.MessageBox.Show(apiResponseString); 

     jsonResponse = returnJson.Deserialize<RootObject>(apiResponseString); 

     return jsonResponse; 

    } 

我的問題是,returnJson.Deserialize(apiResponseString);似乎返回null,隨後使此失敗。

我在想什麼?我認爲我在這個階段有點盲目盲目。

在此先感謝

+0

作爲一個方面說明:我會建議你使用[Json.NET圖書館(HTTP://www.newtonsoft .com/json) – Jim

回答

1

有幾個與Application類問題:

  • 您已經定義Application.Error_Code是一個整數:

    public int Error_Code { get; set; } 
    

    但事實上,在JSON,它有一個空值:

    "Error_Code": null, 
    

    因此,Error_Code需要是參考類型(string)或可爲空值類型(int?),具體取決於非空時的保留類型。

  • 您已經定義Centrelink_Statusint,但在JSON它是一個字符串:

    "Centrelink_Status": "Receiving_Logons" 
    

    因此它需要在數據模型中的字符串爲好。

因此您Application類應該是這樣的:

public class Application 
{ 
    public int App_ID { get; set; } 
    public string App_Ref { get; set; } 
    public string Status { get; set; } 
    public int? Error_Code { get; set; } // Or string, if not numeric 
    public string Error_Message { get; set; } 
    public DateTime Create_Dt { get; set; } 
    public DateTime Modify_Dt { get; set; } 
    public string Client_Name { get; set; } 
    public string Client_Code { get; set; } 
    public string Centrelink_Status { get; set; } 
} 

您也可能想使這些DateTime特性可爲空,如果有在JSON一個null價值的機會。

順便說一句,當我試圖反序列化JSON這樣,我得到了一個異常拋出,而不是一個空值返回:

System.InvalidOperationException was unhandled 
    Message="Cannot convert null to a value type." 
    Source="System.Web.Extensions" 
    StackTrace: 

在您的實際代碼,你捕捉和吞嚥異常?這是一個糟糕的主意,因爲它往往會隱藏像這樣的錯誤。至少,在調試時,只要發生任何異常(包括第一次機會異常),就應該中斷 - 即使這是而不是的默認行爲。請參閱Managing Exceptions with the Debugger。如果您發現某些類型的異常經常被拋出並且與調試無關,您可以選擇性地重新忽略它們。如果你這樣做了,那麼這個bug可能會更直接地追蹤到。誠然,這個錯誤並不是很明顯,但它確實提供了一個提示。如果你使用反序列化JSON的,錯誤信息將更加清晰:

Newtonsoft.Json.JsonSerializationException occurred 
    Message="Error converting value {null} to type 'System.Int32'. Path 'Response.Applications[0].Error_Code', line 9, position 26." 
    Source="Newtonsoft.Json" 
    StackTrace: 
     at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType) in C:\Development\Releases\Json\Working\Newtonsoft.Json\Working-Signed\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 986 
    InnerException: System.InvalidCastException 
     Message="Null object cannot be converted to a value type." 
     Source="mscorlib" 
     StackTrace: 
      at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) 
      at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType) in C:\Development\Releases\Json\Working\Newtonsoft.Json\Working-Signed\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 979 
     InnerException: 
+0

你是一個傳奇人物!謝謝! –