将JSON反序列化为C#类

时间:2014-07-31 06:38:19

标签: c# json.net

以下是我在成功创建新的"作业代码"后从REST API获得的(稍微)精简的响应。条目。我需要将响应反序列化到某些类中,但我很难过。

作为参考,我在.NET 3.5中使用JSON.NET(在SQL Server 2008 R2中的SSIS脚本中运行)来尝试反序列化。这是JSON - 我显然无法控制它,因为它来自其他人的API:

{
   "results":{
      "jobcodes":{
         "1":{
            "_status_code":200,
            "_status_message":"Created",
            "id":444444444,
            "assigned_to_all":false,
            "billable":true,
            "active":true,
            "type":"regular",
            "name":"1234 Main Street - Jackson"
         },
         "2":{
            "_status_code":200,
            "_status_message":"Created",
            "id":1234567890,
            "assigned_to_all":false,
            "billable":true,
            "active":true,
            "type":"regular",
            "name":"4321 Some Other Street - Jackson"
         }
      }
   }
}

在我的C#代码中,我确实有一个" JobCode" class defined,它只将JSON值部分映射到属性 - 我对返回给我的所有数据都不感兴趣:

[JsonObject]
class JobCode
{
    [JsonProperty("_status_code")]
    public string StatusCode { get; set; }
    [JsonProperty("_status_message")]
    public string StatusMessage { get; set; }
    [JsonProperty("id")]
    public string Id {get; set;}
    [JsonProperty("name")]
    public string Name { get; set; }

    //-------------------------------------------------------------------------------
    // Empty constructor for JSON serialization support
    //-------------------------------------------------------------------------------

    public JobCode() { }
}

我试图通过此调用反序列化数据:

newResource = JsonConvert.DeserializeObject<JobCode>(jsonResponse);

其中jsonResponse是上面输出的代码。
当我执行代码时,&#34; newResource&#34;总是回来为null - 这并不意外,因为我知道数据中实际上有多个作业代码,而且这段代码试图将其反序列化为单个JobCode对象。我尝试创建一个名为&#34; JobCodes&#34;看起来像这样:

class JobCodes
{
    [JsonProperty("jobcodes")]
    public List<JobCode>_JobCodes { get; set; }
}

然后我试着说这个:

newResource = JsonConvert.DeserializeObject<JobCodes>(jsonResponse);

但问题仍然存在 - 我的返回对象为null。 我认为,让我失望的是&#34; 1&#34;和&#34; 2&#34;身份标识。我不知道如何考虑他们在我的对象设计中的存在和/或JSON.NET类/属性属性的使用,如[JsonObject],[JsonProperty]等。

当我通过JSON2CSharp运行JSON数据时,它构造了一些奇怪的类,因此没有被证明太有效。我已经使用几个不同的验证器验证了JSON,并且都检查了 - 我只是不知道我在这里丢失了什么。

归根结底,我想从JSON数据中返回一个List,但是我很难知道我需要做些什么才能实现这一目标。

3 个答案:

答案 0 :(得分:45)

你的问题有两个:

  1. 您没有在根级别定义的类。类结构需要匹配整个 JSON,你不能只从中间反序列化。
  2. 每当您有一个可以更改密钥的对象时,您需要使用Dictionary<string, T>。普通班级不适用于此; List<T>
  3. 也不会

    让你的课程如下:

    class RootObject
    {
        [JsonProperty("results")]
        public Results Results { get; set; }
    }
    
    class Results
    {
        [JsonProperty("jobcodes")]
        public Dictionary<string, JobCode> JobCodes { get; set; }
    }
    
    class JobCode
    {
        [JsonProperty("_status_code")]
        public string StatusCode { get; set; }
        [JsonProperty("_status_message")]
        public string StatusMessage { get; set; }
        [JsonProperty("id")]
        public string Id { get; set; }
        [JsonProperty("name")]
        public string Name { get; set; }
    }
    

    然后,像这样反序列化:

    RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
    

    Working demo here

答案 1 :(得分:5)

优秀的答案!

对于那些可能需要更多JSON类配置帮助的人,请尝试:http://json2csharp.com/#

自动生成类的一种很好的方法!

甚至更容易,在VS中,转到:

  

编辑 - &gt;选择性粘贴 - &gt;粘贴为JSON类

答案 2 :(得分:2)

因为您无法更改JSON的方案,并且您无法设置常量的属性,我建议您使用JObject

var jobject = JObject.Parse(json);

var results = jobject["results"];
var jobcodes = results["jobcodes"];

var output = jobcodes.Children<JProperty>()
                     .Select(prop => prop.Value.ToObject<JobCode>())
                     .ToList();

警告:代码假定JSON始终处于正确的架构中。您还应该处理无效的模式(例如,属性不是JobCode方案)。