Solved

Need help posting JSON arrays in a complex object

Posted on 2013-10-22
11
1,387 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 74

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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
While working on Silverlight and WCF application, I faced one issue where fault exception occurred at WCF operation contract is not getting propagated to Silverlight client. So after searching net I came to know that it was behavior by default for s…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

706 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

12 Experts available now in Live!

Get 1:1 Help Now