Solved

trying to consume a c# json webservice

Posted on 2014-12-04
16
332 Views
Last Modified: 2014-12-09
very new to c# development, but familiar with other web dev technologies

I'm trying to create an app (from this tutorial) that consumes json data from an external web service and am having difficulties mapping the data to my json class that I created. Here is the code I'm using:

    class Program
    {
            var url = "http://www.abc.com?params=values";
            getJSONResponse(url);
        }

        static void getJSONResponse(string url)
        {
            var wc = new WebClient();
            var response = wc.DownloadString(url);

            // Create the Json serializer and parse the response
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(OrderDataResponse));
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(response)))
            {
                var orderData = (OrderDataResponse)serializer.ReadObject(ms);
            }
        }
    }

    public class OrderDataResponse
    {
        public string ccg_pid { get; set; }
        public string description { get; set; }
        public int sku { get; set; }
        public int balance_on_hand { get; set; }
    }
}

Open in new window


when I type the url into the browser, I get the following back, so I know I'm getting correct data:

[{"ccg_pid":"12345            ","description":"some description                 ","sku":1234,"balance_on_hand":46}]

Open in new window


when I run my app, and inspect the response variable, I see the data listed above in it. however, when I inspect the orderData object, all of its properties are null or zero.

Any ideas on what I'm doing wrong?
0
Comment
Question by:Big Monty
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 6
  • 2
16 Comments
 
LVL 10

Expert Comment

by:Walter Padrón
ID: 40481919
I suggest you to use Json.NET see http://json.codeplex.com/ it has more options than DataContractJsonSerializer

Json.NET documentation can be found here http://james.newtonking.com/projects/json/help/

Best regards
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40481925
I'd prefer not to have to add any additional dependencies if possible.
0
 
LVL 10

Expert Comment

by:Walter Padrón
ID: 40481938
Add DataContract attributes to the class as

   [DataContract]
    public class OrderDataResponse
    {
       [DataMember(Name = "ccg_pid")]
        public string ccg_pid { get; set; }
   ...
    }

Open in new window


Best regards
0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 33

Author Comment

by:Big Monty
ID: 40482974
i tried that but same results

    [DataContract]
    public class OrderDataResponse
    {
        [DataMember(Name = "ccg_pid")]
        public string ccg_pid { get; set; }
        [DataMember(Name = "description")]
        public string description { get; set; }
        [DataMember(Name = "sku")]
        public int sku { get; set; }
        [DataMember(Name = "balance_on_hand")]
        public int balance_on_hand { get; set; }
    }

Open in new window

0
 
LVL 33

Author Comment

by:Big Monty
ID: 40483199
it looks like the [] in my string are causing the issue, if i take them out, my original code works. digging deeper, I am now getting the message:

Additional information: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'xxx.OrderDataResponse' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

it seems like I have to convert my response to an object maybe? how would i do that?
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40483455
I've requested that this question be closed as follows:

Accepted answer: 0 points for Big Monty's comment #a40483199

for the following reason:

figured out the solution, had to convert my responseData variable to a List
0
 
LVL 10

Accepted Solution

by:
Walter Padrón earned 500 total points
ID: 40483415
Yes the "[]" are wrong in the response, this code works and you do not need to conver to a List

using System;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

[DataContract]
public class OrderDataResponse
{
    [DataMember(Name = "ccg_pid")]
    public string ccg_pid { get; set; }
    [DataMember(Name = "description")]
    public string description { get; set; }
    [DataMember(Name = "sku")]
    public int sku { get; set; }
    [DataMember(Name = "balance_on_hand")]
    public int balance_on_hand { get; set; }
}
                                          
                                          

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            OrderDataResponse o = new OrderDataResponse() { ccg_pid = "12345", description = "some description", sku = 1234, balance_on_hand = 46 };

            var serializer = new DataContractJsonSerializer(typeof(OrderDataResponse));

            // Getting a json response
            var ms1 = new MemoryStream();
            serializer.WriteObject(ms1, o);
            ms1.Position = 0;
            var response = new StreamReader(ms1).ReadToEnd();


            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(response)))
            {
                var orderData = (OrderDataResponse)serializer.ReadObject(ms);
            }
        }
    }
}

Open in new window

0
 
LVL 10

Assisted Solution

by:Walter Padrón
Walter Padrón earned 500 total points
ID: 40483427
With an array works too

using System;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

[DataContract]
public class OrderDataResponse
{
    [DataMember(Name = "myarray")]
    public int[] myarray { get; set; }
}
                                          

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var serializer = new DataContractJsonSerializer(typeof(OrderDataResponse));

            // Getting a json response
            OrderDataResponse o = new OrderDataResponse() { myarray = new[] { 1, 2, 3, 4 } };

            var ms1 = new MemoryStream();
            serializer.WriteObject(ms1, o);
            ms1.Position = 0;
            var response = new StreamReader(ms1).ReadToEnd();


            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(response)))
            {
                var orderData = (OrderDataResponse)serializer.ReadObject(ms);
            }
        }
    }
}

Open in new window

0
 
LVL 33

Author Comment

by:Big Monty
ID: 40483459
unfortunately the data is coming from a 3rd party web service, which I don't have access to.

thanks for the help!
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40484045
Yes the "[]" are wrong in the response...
No they are not:

Screenshot
The problem is that you don't pass the correct type during initialization of the DataContractJsonSerializer. Your JSON in this instance represents an array of things; you should be initializing with an array type:

e.g.

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(OrderDataResponse[]));
string json = "[{\"ccg_pid\":\"12345            \",\"description\":\"some description                 \",\"sku\":1234,\"balance_on_hand\":46}]";
MemoryStream ms = new MemoryStream();
StreamWriter writer = new StreamWriter(ms);
OrderDataResponse[] data;

writer.Write(json);
writer.Flush();
ms.Position = 0;
data = (OrderDataResponse[])serializer.ReadObject(ms);

Open in new window

0
 
LVL 10

Expert Comment

by:Walter Padrón
ID: 40487413
@kaufmed he wants to deserialize to a class object, so he need to remove [] in order to succeed. If webservice returns more than one object he need to deserialize to an array as you suggested.
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40487845
thanks for the continued discussion, I'm learning as I go here :)

I decided to check out the json.net package and converted my code over to it:

        private List<CCG_OrderData>getCGData(string url)
        {
            var wc = new WebClient();
            var response = wc.DownloadString(url);
            return JsonConvert.DeserializeObject<List<CCG_OrderData>>(response);
        }

Open in new window


everything seems to work, I just don't understand why I need to convert it to a list, although I'm unsure of why I need to convert it to some kind of collection object (such as a list), when I didn't, it failed. Is it because the json I'm getting back has brackets surrounding it, thus implying an array? just trying to understand what I'm doing here :)

I'm going to be posting another question in a few minutes, something related to this. I'll post a link to it in here once I open it up.
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40487883
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40488081
Is it because the json I'm getting back has brackets surrounding it, thus implying an array?
Yes. And actually, it doesn't imply an array; it is an array. You may want to familiarize yourself with JSON syntax.
0
 
LVL 10

Expert Comment

by:Walter Padrón
ID: 40489246
More info here
http://www.w3schools.com/json/json_syntax.asp

A webservice is a CONTRACT between the webservice and the client, if they return a deserialized object or an array of objects you need program accordingly. Also the webservice must have an wsdl that describes  the functionality and the return types, try to call the url without any parameters.
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40489340
Yes. And actually, it doesn't imply an array; it is an array

poor wording on my part, I know it's an array of objects. I've used JSON a lot in the past, in classic asp, which is where my expertise lies. I just got hired at a new job (as a classic asp guy) and the first project they gave me was this C# project. Thankfully they understand my skills are limited and are giving me more time to get it done :)
0

Featured Post

Technology Partners: 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!

Question has a verified solution.

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

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

739 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