【问题标题】:Deserializing JSON block with nested array of embedded objects using JSON.NET failing?使用 JSON.NET 使用嵌套的嵌入式对象数组反序列化 JSON 块失败?
【发布时间】:2014-08-11 18:08:08
【问题描述】:

以下是我在 Windows 应用商店应用程序 (Win 8.1) 中进行的 REST API 调用的 JSON 响应。它包含来自 REST API 调用的结果页面,每个结果(行)都是一个 PropertyMaster 记录/对象。下面是 Visual Studio 2013 使用 Paste Special as JSON IDE 功能创建的 JSON 类。如您所见,PropertyMaster 对象有一个 addresses 字段,该字段是 Address 对象的数组。如果您查看 JSON,您将看到第一个结果在 addresses JSON 数组中确实有一个有效的 Address 对象。但是,当我使用以下调用反序列化 JSON 响应时:

JsonConvert.DeserializeObject<PropertyRecordsResponse>(json);

PropertyMaster 对象中的addresses 字段为NULL。我没有收到 JSON.NET 引发的任何异常,那么为什么没有将 addresses JSON 数组的内容正确解析为 Address 对象数组?任何有关如何追踪和解决此问题的提示都表示赞赏。

注意:我确实找到了这个关于反序列化嵌套对象数组的帖子:

Deserializing json string with array of array with Json.NET

但我发誓我之前在 JSON 中有嵌套的对象数组,并且不需要采取特殊操作来反序列化它们。

来自 API 调用的 JSON 响应

{
    "page": {
        "totalRows": 13
    },
    "records": [
        {
            "display": "14CAP-00000005",
            "module": "Building",
            "assignToInfo": {
                "totalJobCost": "0.0"
            },
            "id": "DUB14-00000-0000I",
            "type": {
                "id": "Building-Mobile-Mobile-Tony",
                "display": "Building/Mobile/Mobile/Tony"
            },
            "status": {
                "id": "Ready.cto.cIssue",
                "display": "Ready to Issue"
            },
            "openDate": "2014-08-07"
        },
        {
            "display": "14CAP-00000006",
            "module": "Building",
            "assignToInfo": {
                "totalJobCost": "0.0"
            },
            "id": "DUB14-00000-0000J",
            "type": {
                "id": "Building-Mobile-Mobile-Tony",
                "display": "Building/Mobile/Mobile/Tony"
            },
            "status": {
                "id": "Ready.cto.cIssue",
                "display": "Ready to Issue"
            },
            "openDate": "2014-08-07"
        },
        {
            "addresses": [
                {
                    "id": "999974830-924597381",
                    "display": "233 Camino Ramon Suite 500, San Ramon, CA, 94583",
                    "houseNumber": "233",
                    "streetName": "Camino Ramon",
                    "unit": "500",
                    "unitType": "Suite",
                    "state": "CA",
                    "postalCode": "94583",
                    "city": "San Ramon",
                    "isPrimary": "True",
                    "enabled": true,
                    "entityState": "Unchanged"
                }
            ]
        }
    ]
}

VS2013 为反序列化创建的类

public class PropertyRecordsResponse
{
    public Page page { get; set; }
    public PropertyMaster[] records { get; set; }

    /// <summary>
    /// Deserializes a JSON response from an Accela API call into a property records response object (and sub-objects).
    /// </summary>
    /// <param name="json">The JSON response in string form.</param>
    public static PropertyRecordsResponse ParseJSON(string json)
    {

        return JsonConvert.DeserializeObject<PropertyRecordsResponse>(json);
    }
}

/// <summary>
/// One page of results as returned by an Accela REST API method that returns property records.
/// </summary>
public class Page
{
    public int totalRows { get; set; }
    public bool hasMore { get; set; }
}

public class PropertyMaster
{
    public Address[] addresses { get; set; }
    public string display { get; set; }
    public string module { get; set; }
    public string name { get; set; }
    public Assigntoinfo assignToInfo { get; set; }
    public User user { get; set; }
    public string createdDate { get; set; }
    public string id { get; set; }
    public string description { get; set; }
    public bool isPrivate { get; set; }
    public RecType type { get; set; }
    public Status status { get; set; }
    public Department department { get; set; }
    public Staffperson staffPerson { get; set; }
    public string assignDate { get; set; }
    public string scheduleDate { get; set; }
    public string scheduleTime { get; set; }
    public string openDate { get; set; }
    public string priority { get; set; }
    public string shortNotes { get; set; }
    public string templateName { get; set; }
}

public class Assigntoinfo
{
    public string totalJobCost { get; set; }
    public string completeDate { get; set; }
    public string AssignDate { get; set; }
    public string scheduledDate { get; set; }
    public string assignStaff { get; set; }
    public string assignDepartment { get; set; }
    public string priority { get; set; }
}

public class User
{
    public string firstName { get; set; }
    public string lastName { get; set; }
    public string civicId { get; set; }
    public string email { get; set; }
}

public class RecType
{
    public string id { get; set; }
    public string display { get; set; }
    public string module { get; set; }
    public string group { get; set; }
    public string subGroup { get; set; }
    public string category { get; set; }
    public string type { get; set; }
    public string security { get; set; }
    public string[] inspectionGroups { get; set; }
    public string[] standardCommentsGroupIds { get; set; }
}

public class Status
{
    public string id { get; set; }
    public string display { get; set; }
}

public class Department
{
    public string id { get; set; }
    public string display { get; set; }
    public string agency { get; set; }
    public string bureau { get; set; }
    public string division { get; set; }
    public string section { get; set; }
    public string group { get; set; }
    public string subGroup { get; set; }
    public string subGroupDescription { get; set; }
}

public class Staffperson
{
    public string id { get; set; }
    public string display { get; set; }
    public string agencyCode { get; set; }
    public string auditStatus { get; set; }
    public string bureauCode { get; set; }
    public string divisionCode { get; set; }
    public string firstName { get; set; }
    public string groupCode { get; set; }
    public string lastName { get; set; }
    public string officeCode { get; set; }
    public string sectionCode { get; set; }
    public string serviceProviderCode { get; set; }
    public string userStatus { get; set; }
}

public class Address
{
    public string id { get; set; }
    public string display { get; set; }
    public string addressFormat { get; set; }
    public string houseNumber { get; set; }
    public string houseNumberFraction { get; set; }
    public string streetDirection { get; set; }
    public string streetName { get; set; }
    public string streetSuffix { get; set; }
    public string streetSuffixDirection { get; set; }
    public string unit { get; set; }
    public string unitEnd { get; set; }
    public string unitType { get; set; }
    public string state { get; set; }
    public string postalCode { get; set; }
    public string city { get; set; }
    public string county { get; set; }
    public string country { get; set; }
    public string isPrimary { get; set; }
    public string xCoordinate { get; set; }
    public string yCoordinate { get; set; }
    public bool enabled { get; set; }
    public string entityState { get; set; }
}

【问题讨论】:

  • 发布一个有效的 json 怎么样?
  • @L.B - 我已将原始 JSON 结果添加到我的帖子中,位于格式化结果下方。查找“RAW JSON RESULT”行。谢谢。如果还有其他问题,那是因为为了简洁起见,我从结果中删除了其他行。第一行完好无损。
  • 是的,JSON 无效。此外,拥有一个名为“Type”的类可能会让您的生活变得困难。
  • 原始 JSON 根据jsonformatter.curiousconcept.com 仍然无效。我通过在最终的} 之前添加] 来验证它,但我不知道这是否是意图。
  • @RobertOschler 我把你的 json 放到json2csharp.com 并使用这些类进行反序列化。您的根对象只有 3 条记录,其中只有一条具有 addresses 字段(并且只有该字段)。

标签: c# json serialization windows-store-apps json.net


【解决方案1】:

看起来address 在 JSON 中的位置不正确。尝试反序列化这个(地址在第二条记录中):

{
   "page":{
      "totalRows":1
   },
   "records":[
      {
         "display":"14CAP-00000005",
         "module":"Building",
         "assignToInfo":{
            "totalJobCost":"0.0"
         },
         "id":"DUB14-00000-0000I",
         "type":{
            "id":"Building-Mobile-Mobile-Tony",
            "display":"Building/Mobile/Mobile/Tony"
         },
         "status":{
            "id":"Ready.cto.cIssue",
            "display":"Ready to Issue"
         },
         "openDate":"2014-08-07"
      },
      {
         "display":"14CAP-00000006",
         "module":"Building",
         "assignToInfo":{
            "totalJobCost":"0.0"
         },
         "id":"DUB14-00000-0000J",
         "type":{
            "id":"Building-Mobile-Mobile-Tony",
            "display":"Building/Mobile/Mobile/Tony"
         },
         "status":{
            "id":"Ready.cto.cIssue",
            "display":"Ready to Issue"
         },
         "openDate":"2014-08-07",
         "addresses":[
            {
               "id":"999974830-924597381",
               "display":"233 Camino Ramon Suite 500, San Ramon, CA, 94583",
               "houseNumber":"233",
               "streetName":"Camino Ramon",
               "unit":"500",
               "unitType":"Suite",
               "state":"CA",
               "postalCode":"94583",
               "city":"San Ramon",
               "isPrimary":"True",
               "enabled":true,
               "entityState":"Unchanged"
            }
         ]
      }
   ]
}

【讨论】:

  • 你是对的。我现在就这个问题与 API 供应商联系。沙盒系统中的记录似乎不完整,考虑到它是开发人员的测试环境,这并不罕见。
猜你喜欢
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-17
  • 1970-01-01
相关资源
最近更新 更多