Solved

Need help posting JSON arrays in a complex object

Posted on 2013-10-22
11
1,443 Views
Last Modified: 2013-10-24
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
Comment
Question by:ITMikeK
11 Comments
 
LVL 47

Assisted Solution

by:dlethe
dlethe earned 334 total points
ID: 39591465
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
 

Author Comment

by:ITMikeK
ID: 39591711
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
 
LVL 47

Accepted Solution

by:
dlethe earned 334 total points
ID: 39591793
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
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 166 total points
ID: 39593017
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
 

Author Comment

by:ITMikeK
ID: 39593155
I'll be trying both suggestions in the morning.  Thank you!
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:ITMikeK
ID: 39593160
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
 
LVL 19

Expert Comment

by:Rikin Shah
ID: 39593456
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
 

Author Comment

by:ITMikeK
ID: 39594591
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
 

Author Comment

by:ITMikeK
ID: 39594742
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
 

Author Comment

by:ITMikeK
ID: 39595193
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
 

Author Comment

by:ITMikeK
ID: 39598631
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
As a trusted technology advisor to your customers you are likely getting the daily question of, ‘should I put this in the cloud?’ As customer demands for cloud services increases, companies will see a shift from traditional buying patterns to new…

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now