Wednesday, May 1, 2013

How to Consume a JSON REST API in .NET

In this article I’ll show you how simple it is to consume JSON based APIs from .NET. It requires just a few lines of code, is straight forward and will work across different types of apps. I’ll also show you how to consume an example API synchronously and asynchronously.

But before, let’s talk a bit about the API subject, shall we? (if you are in a hurry, just jump directly to the code).

Consuming web services and APIs will always be a big topic on our industry. Service oriented architectures enable us to create online endpoints to serve many different clients across the digital world. Application programming interfaces (APIs) are nothing new, they have been with us for a long time, and have consumed a lot of our efforts to communicate digital systems. However, web APIs are becoming more and more relevant, since they allows us to communicate thought networks to serve a wide variety of clients.

Representation State Transfer (REST) design models are the predominant software architecture for such distributed systems. Most modern web APIs are designed following the REST principles, resulting in simpler, general, more scalable web services that are easier to consume.

.NET has come a long way in terms of web services architectures. Most of us will remember traditional ASP.NET services, SOAP based services, WCF services and XML-based services without too much excitement. Although they were powerful service oriented technologies and frameworks, not many will say that they were easy to implement. RESTful services have also become the predominant model design in .NET, and now more than ever, consuming and exposing RESTful services relatively easy. However, there seems to be a lot of confusion about how to do such things in the .NET world!

Consuming JSON RESTful services in .NET

With any new version of the .NET framework, and features, we should revise if we can implement functionality in a new, easier and/or simpler way. With all the recent updates to the stack, I wanted to do a review on how to consume JSON APIs from .NET applications. It turns out that there are a lot of discussions on the matter, different opinions, techniques and samples, but I found it difficult to find the right answer straight away.

So, to make it clear, easy and concrete, lets build something right away. We will start with a simple console application project. Fire up Visual Studio (I’m using VS 2012), and create a new console application project.

image

We will implement a simple Weather API client by using the OpenWeatherMap.org JSON API. The API will allow us to locate a city location and get the weather forecast information.

Lets create a new class to manage the API client logic. Right click on the project, select Add->Class. Name it WeatherApiClient.cs.

image

For simplicity, I’ll make the class static, so I can call its methods straight away from the main program class. We will first implement the synchronous client method.

Create a new void method in the class. Let’s call it GetWeatherForecast(). Don;t forget to make it static.

image

Ok, so now we need to decide which mechanism are we going to use to consume the API. In .NET you can use two different classes: WebClient or HttpWebRequest. Without getting into much detail, the popular opinion is that WebClient provides a simpler and easier implementation, while HttpWebRequest allows a more granular control over the way requests are executed.

In this case, we will use the WebClient class. It has a method called DownloadString() which received a string URL and returns a string containing the JSON response. Notice that in order to use WebClient, you will need to add a reference to System.Net to your project.

To implement this first step, just declare a sample URL (you can check in the OpenWeatherMap documentation for one). Then create a new WebClient variable and call the DownloadString() method passing the URL.

image

At this point, we can call our method from the main program class and put a breakpoint on it, so we can check the response from the API. Let’s do that, and make sure the call is working and you are getting the JSON response back as a string result.

image

Let the WebClient make the call and then examine the contents of the response. You should be able to use the Text Visualizer tool to review the JSON response.

image

image

Great. We are actually able to make the call to the API and get the JSON. That was actually quite easy and straight forward. Just like it should be. Now the question is, what do we do with the response?

You might just want to store it, or pass it to another client or something long those lines. But chances are that you actually want to deserialize the response and be able to get an object out of it, so you can work on it more comfortably. For this, we need a JSON serialization/deserialization mechanism (which is quite similar to XML serialization/deserialization tools).

There are a couple of libraries you could use. JSON.NET is one of them (check this article from Scott Hanselman on the subject). However, I would rather use something native and avoid adding dependencies to the solution. It turns out that .NET has a class called DataContractJsonSerializer, which conveniently, lets you serialize objects to JSON and deserialize JSON to objects. 

Now, we need to specify the type of object we want to use to deserialize our JSON response. You would normally have to check the JSON structure, and create the corresponding .NET class in your application, which is honestly, quite tedious. Happily, there is a neat web app called json2csharp that allows you to enter a JSON string (or a URL to a JSON string), and it will generate the corresponding C# class for you!

Copy the JSON response you got from the OpenWeatherMap API and paste it in the json2csharp text field, then click the Generate button.

image

Stop debugging your Visual Studio solution if you haven’t done so. In the Visual Studio project, create a new class and name it WeatherData.cs. Copy the code from json2csharp and paste it in the new class, without overriding the default class code. Notice that the class generated by json2csharp contains several class definitions. image

The last class generated by json2csharp is actually the root object containing the whole response. It will contain all the objects within the JSON string. We want this object to be our WeatherData class. You can rename the RootObject, or copy its properties to our WeatherData class definition.

image

For each of the generated classes, create a property of the same type in the WeatherData main class. To enable the DataContractJsonSerializer to use this class for serializing and deserializing, you need to add the DataContract attribute on the main class, and the DataMember attribute on each of the main class properties. You will need to add a reference to System.Runtime.Serialization to your project.

image

image

Great. Save the class and go back to our WeatherApiClient class. What we need now is to add the code to deserialize the JSON response to get a WeatherData object from it.

For this, you will need to add two using clauses: System.Runtime.Serialization.Json for the DataContractJsonSerializer and System.IO for the MemoryStream we will need.

Declare a new DataContractJsonSerializer passing the WeatherData as the required type. Then create a MemoryStream object from the string response we obtained before from the API. Finally, use the ReadObject() method of the serializer to deserialize the JSON response. You should obtain a nice WeatherData object with all the information we got from the API.

Compile and run the project, using the previous breakpoint. Examine the weatherData object after deserializing the response. You should see all the weather information in your .NET object!

image

image

There you go. That wasn’t difficult at all. You have a data class, which was generated almost entirely for you by json2csharp. Then a main program, where you only had to write one line of code to call your GetWeatherForecast() method. And the WeatherApiClient class itself is just 30 lines of code, of which 6 lines are actually doing the job (the rest is brackets and definitions).

Here is the main code you need:

  1: public static class WeatherApiClient
  2: {
  3:     public static void GetWeatherForecast() 
  4:     {
  5:         var url = "http://api.openweathermap.org/data/2.1/find/city?lat=51.50853&lon=-0.12574&cnt=10";
  6: 
  7:         // Synchronous Consumption
  8:         var syncClient = new WebClient();
  9:         var content = syncClient.DownloadString(url);
 10: 
 11:         // Create the Json serializer and parse the response
 12:         DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(WeatherData));
 13:         using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
 14:         {
 15:             var weatherData = (WeatherData)serializer.ReadObject(ms);
 16:         }
 17:     }
 18: }

Next, I’ll publish the follow up article on how to make the API request asynchronously. I plan to keep working on this topic, and add more popular APIs, including social networks, since I’m sure it would be helpful for many people out there.

You can download the full source code from my Github repository here.

Please take a couple of minutes to leave comments, questions or suggestions. I’m more than happy to get in touch and help you, or learn from whatever you can share.

12 comments:

  1. There are serious risks to strongly coupling to an output model like this. You have to keep in mind that if a field is not included in the output (because it was null or inappropriate for the selected parameters), you run the risk of not including that field in your Csharp object. IMO using JSON.Net to provide a dynamic object from the output JSON is a far safer approach. This also means little to no refactoring to take advantage of any new fields that are added after the fact (commonly done in APIs as it's a non-breaking change).

    ReplyDelete
    Replies
    1. Hi Jason. Thanks a lot for taking the time to leave your comment. Is very helpful. Let me add to some of your points:
      - According to fellow devs, JSON.NET seems to perform very well, and it is supposed to be faster than the default JSON serializer.
      - Even is the JSON output was missing some values, that should not break the object. I can test it by just commenting out some of the C# object. Serialization still works.
      - IMO, changing the JSON object returned by an API endpoint, is in fact a breaking change. However, removing a field from the JSON string response, doesn't break the serialization either.
      - json2csharp is just a tool to help you structure your C# objects. Clearly, you should always check API documentation and test it under different scenarios, to make sure you are not missing data.
      - Having class contracts to generate C# objects might be required. It doesn't mean that is the only way, but it might be precisely what you want to do.

      That being said, I'm keen to use JSON.NET, specially for WP development. I'll try it out and post my findings. Again, there's never one true solution for every problem!

      Delete
  2. tanks a lot. That's really helpful.

    ReplyDelete
  3. Thanks for your post, it really great and helped me to make 'boring' works faster!

    ReplyDelete
  4. Thank you very much for this post.

    ReplyDelete
  5. Thank for your nice explanation

    ReplyDelete
  6. Very fast, nice and simple to implement!

    ReplyDelete
  7. Hi,
    I am totally new to this api world.I want to call api with get,post delete methods.I understood only your post a bit after searching alot in the internet.Please post some other related examples for get post methods.

    ReplyDelete
  8. Thanks a lot man.
    Thanks for ppl like you for makeing our programming life easy .. Thanks again for spending time to help others... Peace

    ReplyDelete
  9. Great post. I follow it using Rotting Tomatoes api and worked perfectly. I just have to add some references not only to the project but at the top of the classes, and that´s not shown in your code, but it's fine.

    ReplyDelete
  10. Thanks for this great article for an enterance from c# to rest and json.

    ReplyDelete