【问题标题】:Why is my JSon giving me nulls on sub-arrays?为什么我的 JSON 在子数组上给我空值?
【发布时间】:2013-10-24 15:50:08
【问题描述】:

我一直在尝试让传入的 Json 消息进行序列化(并正确反序列化)。首先是我通过 POSTMAN 发布到我们的 MVC 休息服务的传入 Json。通过 JsonLint 对其进行验证。主要问题是两个子数组,accounts 和 propertyValues 作为空值传入。 serviceAddresses 是 profilePush 的一个数组成员,它的其他属性正在填充。在我将它们全部放入 DataContracts 之前,我得到了 serviceAddresses 的空值。我在这里错过了什么?

------------ 传入的 JSON ------

 {
    "userId" : 15,
    "firstName" : "Michael",
    "lastName" : "Smith",
    "email" : "msmith@google.org",
    "deleted" : false,
    "serviceAddresses" : [ {
    "addressId" : 18,
    "address1" : "8401 Lorain Road",
    "address2" : "Suite 10A",
    "city" : "Newton Falls",
    "state" : "OH",
    "zip" : "44021",
    "deleted" : false,
    "accounts" : [],
    "propertyAttributes" : {
        "attr_name" : "heat_type",
        "attr_value" : "Gas",
        "attr_name" : "hot_water_heater_type",
        "attr_value" : "Gas",
        "attr_name" : "rent_own",
        "attr_value" : "Own",
        "attr_name" : "sq_ft",
        "attr_value" : "2000",
        "attr_name" : "stove_type",
        "attr_value" : "Gas"
                           }
                       }
     ]
   }





    [HttpPost]
    public JsonResult profileInformationPush(profilePush profile )
    {
          bool bError = false;

          string s = JsonConvert.SerializeObject(profile);

          profilePush deserializedProfile =
          JsonConvert.DeserializeObject<profilePush>(s);

    }

--------这就是“个人资料”进入程序的样子--------------

{"UserId":15,"FirstName":"Michael","LastName":"Smith","Email":"msmith@google.org","Deleted":"False","ServiceAdresses":[{"AddressId":18,"Address1":"8401 Lorain Road","Address2":"Suite 10A","City":"Newton Falls","State":"OH","Zip":"44021","Deleted":"False","Accounts":null,"PropertyAttributes":null}]}


--------------Data Contracts ---------------------



  [DataContract]
        public class accountInfo
        {
            [DataMember(Name="accountNumber", EmitDefaultValue = false)]
            public string AccountNumber { get; set; }
            [DataMember(Name="deleted", EmitDefaultValue = false)]
            public string Deleted { get; set; }
        }



    [DataContract]
    public class PropertyAttributes
    {
        [DataMember(Name="attr_name", EmitDefaultValue = false)]
        public string Attr_Name { get; set; }
        [DataMember(Name="attr_value", EmitDefaultValue = false)]
        public string Attr_Value { get; set; }

    }

    [DataContract]
    public class ServiceAddresses
    {
        [DataMember(Name="addressId", EmitDefaultValue = false)]
        public int AddressId { get; set; }
        [DataMember(Name="address1", EmitDefaultValue = false)]
        public string Address1 { get; set; }
        [DataMember(Name="address2", EmitDefaultValue= false)]
        public string Address2 { get; set; }
        [DataMember(Name="city", EmitDefaultValue = false)]
        public string City { get; set; }
        [DataMember(Name="state", EmitDefaultValue = false)]
        public string State { get; set; }
        [DataMember(Name="zip", EmitDefaultValue = false)]
        public string Zip { get; set; }
        [DataMember(Name="deleted", EmitDefaultValue = false)]
        public string Deleted { get; set; }
        [DataMember(Name="accounts", EmitDefaultValue = false)]
        public accountInfo[] Accounts { get; set; }

        [DataMember(Name = "propertyAttributes", EmitDefaultValue = false)]
        public PropertyAttributes[] PropertyAttributes { get; set; }
    }

    [DataContract]
    public class profilePush
    {
        [DataMember(Name="userId", EmitDefaultValue= false)]
        public int UserId { get; set; }
        [DataMember(Name="firstName", EmitDefaultValue = false)]
        public string FirstName { get; set; }
        [DataMember(Name="lastName", EmitDefaultValue = false)]
        public string LastName { get; set; }
        [DataMember(Name="email", EmitDefaultValue = false)]
        public string Email { get; set; }
        [DataMember(Name="deleted", EmitDefaultValue = false)]
        public string Deleted { get; set; }
        [DataMember(Name="serviceAddresses", EmitDefaultValue = false)]
        public ServiceAddresses[] ServiceAddresses { get; set; }
    }

【问题讨论】:

  • 这是什么消耗?它是 Web 服务还是其他类型的服务?
  • JSONLint 验证它,但默默地拒绝所有重复的 attr_name 和 attr_value 字段,只保留最后一个。这不是真正有效的 JSON。这就像做 x = 1; x = 2; x = 3; 然后想要所有 3 个值。

标签: c# arrays json serialization datacontracts


【解决方案1】:

问题在于这个 JSON:

"propertyAttributes" : {
    "attr_name" : "heat_type",
    "attr_value" : "Gas",
    "attr_name" : "hot_water_heater_type",
    "attr_value" : "Gas",
    "attr_name" : "rent_own",
    "attr_value" : "Own",
    "attr_name" : "sq_ft",
    "attr_value" : "2000",
    "attr_name" : "stove_type",
    "attr_value" : "Gas"
}

还有你的结构:

    [DataMember(Name = "propertyAttributes", EmitDefaultValue = false)]
    public PropertyAttributes[] PropertyAttributes { get; set; }

他们不适合。根据您的 JSON,propertyAttributesobject,而不是 array。而且由于 json 反序列化器需要一个数组但得到一个对象,因此它无法填充您的属性并且您得到 null。

你确定这是你得到的 JSON 吗?它甚至无效,因为属性名称在一个对象中多次使用。这是正确的:

"propertyAttributes": [
    {
        "attr_name": "heat_type",
        "attr_value": "Gas"
    }, {
        "attr_name": "hot_water_heater_type",
        "attr_value": "Gas"
    }
]

这里你得到一个数组[...]对象{..},每个对象都有一个属性attr_name和一个属性attr_value

【讨论】:

  • 那是客户端发送的 Json,它实际上通过 JsonLint 作为有效传递。没有注意到缺少将 propertyAttributes 表示为数组的括号。将联系客户修复他们的发送应用程序。谢谢!
猜你喜欢
  • 2013-12-02
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
  • 1970-01-01
  • 2014-01-22
相关资源
最近更新 更多