2016-11-11 84 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

你是一个传奇人物!谢谢! –