Solved

trying to consume a c# json webservice

Posted on 2014-12-04
16
328 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
Comment Utility
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 32

Author Comment

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

Expert Comment

by:Walter Padrón
Comment Utility
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
 
LVL 32

Author Comment

by:Big Monty
Comment Utility
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 32

Author Comment

by:Big Monty
Comment Utility
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 32

Author Comment

by:Big Monty
Comment Utility
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
Comment Utility
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
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 32

Author Comment

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

thanks for the help!
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
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
Comment Utility
@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 32

Author Comment

by:Big Monty
Comment Utility
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 32

Author Comment

by:Big Monty
Comment Utility
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
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
Comment Utility
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 32

Author Comment

by:Big Monty
Comment Utility
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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
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 is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

762 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

9 Experts available now in Live!

Get 1:1 Help Now