trying to consume a c# json webservice

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?
LVL 34
Big MontySenior Web Developer / CEO of ExchangeTree.org Asked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
Walter PadrónConnect With a Mentor Commented:
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
 
Walter PadrónCommented:
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
 
Big MontySenior Web Developer / CEO of ExchangeTree.org Author Commented:
I'd prefer not to have to add any additional dependencies if possible.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
Walter PadrónCommented:
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
 
Big MontySenior Web Developer / CEO of ExchangeTree.org Author Commented:
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
 
Big MontySenior Web Developer / CEO of ExchangeTree.org Author Commented:
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
 
Big MontySenior Web Developer / CEO of ExchangeTree.org Author Commented:
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
 
Walter PadrónConnect With a Mentor Commented:
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
 
Big MontySenior Web Developer / CEO of ExchangeTree.org Author Commented:
unfortunately the data is coming from a 3rd party web service, which I don't have access to.

thanks for the help!
0
 
käµfm³d 👽Commented:
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
 
Walter PadrónCommented:
@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
 
Big MontySenior Web Developer / CEO of ExchangeTree.org Author Commented:
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
 
Big MontySenior Web Developer / CEO of ExchangeTree.org Author Commented:
0
 
käµfm³d 👽Commented:
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
 
Walter PadrónCommented:
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
 
Big MontySenior Web Developer / CEO of ExchangeTree.org Author Commented:
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
All Courses

From novice to tech pro — start learning today.