C# 反序列化Json Web API响应-嵌套对象

C# 反序列化Json Web API响应-嵌套对象,c#,json,ssis,javascriptserializer,json.net,C#,Json,Ssis,Javascriptserializer,Json.net,我通过SSIS脚本组件获得一个Web API JSON响应,该响应以以下格式返回: { "Success": true, "Response": { "Applications": [ { "App_ID": 1638486, "App_Ref": "Test Example", "Status": "Complete", "Error_Code": null, "Error_Me

我通过SSIS脚本组件获得一个Web API JSON响应,该响应以以下格式返回:

    {
  "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;

    }
公共类应用程序
{
public int App_ID{get;set;}
公共字符串App_Ref{get;set;}
公共字符串状态{get;set;}
公共整数错误\u代码{get;set;}
公共字符串错误\u消息{get;set;}
公共日期时间创建{get;set;}
公共日期时间修改{get;set;}
公共字符串客户端名称{get;set;}
公共字符串客户端代码{get;set;}
public int Centrelink_Status{get;set;}
}
公众课堂反应
{
公共列表应用程序{get;set;}
公共字符串Current_Dt{get;set;}
公共字符串Last_App_Dt{get;set;}
公共整数计数{get;set;}
公共整数总计{get;set;}
}
公共类根对象
{
公共bool成功{get;set;}
公共响应{get;set;}
}
这就是我用来得到答案的方法。
私有根对象GetWebServiceResult(字符串vAPIUrl)
{
字符串vAPIToken=Variables.APIToken;
//创建Web请求
HttpWebRequest apireq=(HttpWebRequest)WebRequest.Create(vAPIUrl);
apireq.ContentType=“应用程序/json”;
apireq.Method=“POST”;
字符串jsonPostStr=“{\”设置\“:{\”API \”令牌\“:\”+vAPIToken+“\”}、\”有效负载\“:{}}”;
byte[]postString=Encoding.UTF8.GetBytes(jsonPostStr);
apireq.ContentLength=postString.Length;
Stream jsonStream=apireq.GetRequestStream();
Write(postString,0,postString.Length);
jsonStream.Close();
//获取Web响应
HttpWebResponse apirsp=(HttpWebResponse)apireq.GetResponse();
RootObject jsonResponse=null;
流jsonRspStream=apirsp.GetResponseStream();
字符串apResponseString=null;
使用(StreamReader=newstreamreader(jsonRspStream))
{
apiResponseString=reader.ReadToEnd();
控制台写入线(apiResponseString);
reader.Close();
}
JavaScriptSerializer returnJson=新的JavaScriptSerializer();
//var serialJsonStr=returnJson.Serialize(apiResponseString);
System.Windows.Forms.MessageBox.Show(apResponseString);
jsonResponse=returnJson.Deserialize(apiResponseString);
返回jsonResponse;
}
我的问题是returnJson.Deserialize(apresponsestring)似乎返回null,并随后使其失败

我错过了什么?我认为我在这个阶段有点代码盲


提前感谢

应用程序类有几个问题:

  • 您已将
    应用程序。错误\u code
    定义为整数:

    public int Error_Code { get; set; }
    
    但事实上,在JSON中,它有一个空值:

    "Error_Code": null,
    
    因此,
    Error\u code
    需要是引用类型(
    string
    )或可空值类型(
    int?
    ),这取决于它在非空时所保存的内容

  • 您已经将
    Centrelink\u Status
    定义为
    int
    ,但在JSON中它是一个字符串:

    "Centrelink_Status": "Receiving_Logons"
    
    因此,它也需要是数据模型中的字符串

因此,您的
应用程序
类应该如下所示:

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; }
}
如果JSON中有可能出现
null
值,您可能还希望使这些
DateTime
属性为空

顺便说一句,当我尝试反序列化此JSON时,抛出了一个异常,而不是返回一个空值:

System.InvalidOperationException was unhandled
  Message="Cannot convert null to a value type."
  Source="System.Web.Extensions"
  StackTrace:
在实际代码中,您是否捕获并接受异常?这是一个坏主意,因为它往往隐藏这样的错误。至少,在调试时,无论何时抛出任何异常(包括第一次出现的异常),都应该中断,即使这不是默认行为。看见如果发现某些类型的异常经常被抛出,并且与调试无关,则可以有选择地重新忽略它们。如果您这样做的话,这个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: 

作为旁注:我建议你使用你是一个传奇!非常感谢。