[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1840
  • Last Modified:

Need help posting JSON arrays in a complex object

Greetings,

     I'm trying to test a POST REST service and am using the POSTMAN Chrome plugin.  My classes are listed below and the sample JSON data I'm sending is listed as well.  When it hits my service,  the "sa" list is null.  Any ideas?  Thanks!

I have set the Content-Type and Accept headers to application/json in POSTMAN.

<-------------   JSON Sample --------------------->
{
"userId" : 15,
"firstName" : "Michael",
"lastName" : "Smith",
"email" : "msmith@google.org",
"deleted" : false,
"serviceAdresses" : [ {
 "addressId" : 18,
 "address1" : "8404 Lorain Road",
 "address2" : "Suite 10A",
 "city" : "Chagrin Falls",
 "state" : "OH",
 "zip" : "44023",
 "deleted" : false,
 "accounts" : [],
 "propertyAttributes" : {
     "heat_type" : "Gas",
       "hot_water_heater_type" : "Gas",
       "rent_own" : "Own",
       "sq_ft" : "2000",
       "stove_type" : "Gas"
       }
   }
 ]
}
      

<--------------------   Classes  ----------------------------->

        public class accountInfo
        {
            public string accountName { get; set; }
            public string accountType { get; set; }
            public string deleted { get; set; }
        }

        public class propertyAttributes
        {
            public string att_name { get; set; }
            public string att_value { get; set; }
        }

       public class serviceAddresses
       {
           int addressId {get;set;}
           string address1 {get;set;}
           string address2 {get;set;}
           string city {get;set;}
           string state {get;set;}
           string zip {get;set;}
           bool deleted {get;set;}
           public List<accountInfo> accounts { get; set; }
           public List<propertyAttributes> propertyAttributes {get;set;}


       }

       public class profilePush
       {

           public int userId { get; set; }
           public string firstName { get; set; }
           public string lastName { get; set; }
           public string email { get; set; }
           public string deleted { get; set; }
     
           public List<serviceAddresses> sa { get; set; }


       }
0
ITMikeK
Asked:
ITMikeK
3 Solutions
 
DavidCommented:
For what it is worth, I went to jsonlint.com and verified the JSON is good.  That is half the battle.

You don't have all the code posted, but let's step back and take JSON out of the equation and make sure that everything else works.  Comment all the code out and just submit one field, like the userId.  If this works, then gut feeling it is the accounts giving you a problem.Try commenting that out and seeing if it resolves the problem. Not much value posting that anyway.
0
 
ITMikeKAuthor Commented:
I do get data for the following:

 public int userId { get; set; }
           public string firstName { get; set; }
           public string lastName { get; set; }
           public string email { get; set; }
           public string deleted { get; set; }

sa is null
What other code would you like to see?
0
 
DavidCommented:
try taking out the accounts from the JSON, I really think that is it. Whatever software generates the JSON can certainly suppress sending a null JSON object.

Maybe a library bug, (I'm a UNIX guy), but maybe it is confused between null object and null array?

In your situation is  "address" : null   instead of "address" : []   more appropriate?

(But comment out the address line completely and see if that fixes it)
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
käµfm³d 👽Commented:
Your classes don't exactly match the JSON that you are trying to submit. First, "sa" needs to be "serviceAdresses" or vice-versa. (Side note: "serviceAdresses" is spelled incorrectly.) Next, your "propertyAttributes" class won't work because the property names don't match the attributes in the JSON. I understand what you are trying to accomplish in the second bit, but I don't think the serializer can handle it. You could use the dynamic keyword instead:

public class serviceAddresses
{
    ...

    public dynamic propertyAttributes { get; set; }
}

Open in new window


It wouldn't give you exactly what you want, and you would lose Intellisense support (a down-side of using dynamic), but you would have working deserialization.

profilePush p = JsonConvert.DeserializeObject<profilePush>(json);

Console.WriteLine(p.serviceAddresses[0].propertyAttributes.heat_type);
Console.ReadKey();

Open in new window

0
 
ITMikeKAuthor Commented:
I'll be trying both suggestions in the morning.  Thank you!
0
 
ITMikeKAuthor Commented:
BTW:  Property attributes are dynamic.  There could be any number of key/value pairs.  This is coming from a client application who is "pushing" the data to our server.  And thanks for pointing out the misspelling.  I will bring that to the clients' attention.
0
 
Rikin ShahMicrosoft Dynamics CRM ConsultantCommented:
Hi,

I would suggest using these class definitions if possible:

public class PropertyAttributes
{
    public string heat_type { get; set; }
    public string hot_water_heater_type { get; set; }
    public string rent_own { get; set; }
    public string sq_ft { get; set; }
    public string stove_type { get; set; }
}

public class ServiceAdress
{
    public int addressId { get; set; }
    public string address1 { get; set; }
    public string address2 { get; set; }
    public string city { get; set; }
    public string state { get; set; }
    public string zip { get; set; }
    public bool deleted { get; set; }
    public List<object> accounts { get; set; }
    public PropertyAttributes propertyAttributes { get; set; }
}

public class RootObject
{
    public int userId { get; set; }
    public string firstName { get; set; }
    public string lastName { get; set; }
    public string email { get; set; }
    public bool deleted { get; set; }
    public List<ServiceAdress> serviceAdresses { get; set; }
}

Open in new window

0
 
ITMikeKAuthor Commented:
OK, this is what I've tried so far.  Removing the references to the accounts and propertyAttributes and renaming the serviceAddresses class:

----------------------------------- JSON --------------------------------------------

{
"userId" : 15,
"firstName" : "Michael",
"lastName" : "Smith",
"email" : "msmith@google.org",
"deleted" : false,
"serviceAddresses" : [ {
 "addressId" : 18,
 "address1" : "8401 Lorain Road",
 "address2" : "Suite 10A",
 "city" : "Chagrin Falls",
 "state" : "OH",
 "zip" : "44023",
 "deleted" : false
 
   }
 ]
}

----------------------------------- POST Results via visualizer-------------------------------------------

After serializer:

{"userId":15,"firstName":"Michael","lastName":"Smith","email":"msmith@google.org","deleted":"False","serviceAddresses":[{}]}

Deserialized:
deleted "False"
email "msmith@google.org"
firstName "Michael"
lastName "Smith"
serviceAddresses     Count=1
    address1  null
    address2 null
    addressId 0
    city null
     deleted null
     state null
      zip nul
userId      15


----------------------------------- Classes ---------------------------------------


       public class profilePush
       {

           public int userId { get; set; }
           public string firstName { get; set; }
           public string lastName { get; set; }
           public string email { get; set; }
           public string deleted { get; set; }
     
          public List<sa> serviceAddresses { get; set; }


       }


      public class sa
       {
           int addressId {get;set;}
           string address1 {get;set;}
           string address2 {get;set;}
           string city {get;set;}
           string state {get;set;}
           string zip {get;set;}
           string deleted {get;set;}
     //      public List<accountInfo> accounts { get; set; }
        //   public List<propertyAttributes> propertyAttributes {get;set;}
           


       }


I'm going to try the dynamic thing next.
0
 
ITMikeKAuthor Commented:
The whole dynamic thing was also a bust.  I used the class structures suggested and even removed the "accounts" object, but the servicesAddresses is still coming back null.


--------------------   FROM Visualizer  after Serializing  -----------------------------
{"userId":15,"firstName":"Michael","lastName":"Smith","email":"msmith@google.org","deleted":"False","serviceAdresses":null}

---------------------------  CLASSES -------------------------------------

       public class PropertyAttributes
        {
            public string heat_type { get; set; }
            public string hot_water_heater_type { get; set; }
            public string rent_own { get; set; }
            public string sq_ft { get; set; }
            public string stove_type { get; set; }
        }

        public class ServiceAdresses
        {
            public int addressId { get; set; }
            public string address1 { get; set; }
            public string address2 { get; set; }
            public string city { get; set; }
            public string state { get; set; }
            public string zip { get; set; }
            public string deleted { get; set; }
         //   public List<accountInfo> accounts { get; set; }
            public PropertyAttributes propertyAttributes { get; set; }
        }

        public class profilePush
        {
            public int userId { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public string email { get; set; }
            public string deleted { get; set; }
            public List<ServiceAdresses> serviceAdresses { get; set; }
        }

----------------------------------   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" : "44023",
 "deleted" : false,

 "propertyAttributes" : {
     "heat_type" : "Gas",
       "hot_water_heater_type" : "Gas",
       "rent_own" : "Own",
       "sq_ft" : "2000",
       "stove_type" : "Gas"
       }
   }
 ]
}
0
 
ITMikeKAuthor Commented:
OK, made some progress by changing the classes to DataContracts.  Getting Address information now, but account and propertyAttributes are still coming in as null.




------------   Incoming 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"
       }
   }
 ]
}
      


-------- Serialized JSON POST --------------

{"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; }
           // public string accountType { 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; }
        }
0
 
ITMikeKAuthor Commented:
Figured it out.  The incoming Json for the property attributes was not in array format, but object format.  Fixed it by adding { } after each name/value pair.  Thanks for all of your help anyhow.  I did learn a few things!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now