Solved

trying to consume a c# json webservice

Posted on 2014-12-04
16
330 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
  • 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

Problem Hi all,    While many today have fast Internet connection, there are many still who do not, or are connecting through devices with a slower connect, so light web pages and fast load times are still popular.    If your ASP.NET page …
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

770 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