If we have an app that displays data, the chances are that it comes from somewhere outside the device, say somewhere like the Internet.
To work with JSON responses, we need to install the Newtonsoft.Json
NuGet package or the Json.NET
component. This is an advanced JSON parser; however, we can make use of the DataContractJsonSerializer
type or any other serializer for JSON.
In order to obtain data from the Internet or a local network, we use HTTP requests. In this recipe, we access data from http://jsonplaceholder.typicode.com/posts/1:
{ "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati", "body": "quia et suscipit suscipit recusandae conse" }
[assembly: UsesPermission(Manifest.Permission.Internet)]
HttpClient
and the GetStringAsync()
method:using (var client = new HttpClient()) { var uri = "http://jsonplaceholder.typicode.com/posts/1"; var result = await client.GetStringAsync(uri); }
public class Post { public int Id { get; set; } public int UserId { get; set; } public string Title { get; set; } [JsonProperty("body")] public string Content { get; set; } }
var post = JsonConvert.DeserializeObject<Post>(result);
If we want to send data to the server, we can do something similar, but instead of doing a GET, we do a POST to http://jsonplaceholder.typicode.com/posts:
var newPost = new Post { UserId = 12, Title = "My First Post", Content = "This is some real deep stuff in here!" };
var jsonData = JsonConvert.SerializeObject(newPost);
"application/json"
:var content = new StringContent( jsonData, Encoding.UTF8, "application/json");
var uri = "http://jsonplaceholder.typicode.com/posts"; var result = await client.PostAsync(uri, content);
Doing a POST will return a result from the server, which we use to determine whether everything went well:
EnsureSuccessStatusCode()
method to throw an exception if there is a problem:result.EnsureSuccessStatusCode();
IsSuccessStatusCode
property for a successful result:var success = result.IsSuccessStatusCode;
Content
property:var resultString = await result.Content.ReadAsStringAsync(); var post = JsonConvert.DeserializeObject<Post>(resultString);
There are many ways for an app to communicate with the outside world. These include technologies used on the Internet, such as HTTP and FTP, as well as via more local technologies such as Bluetooth or NFC. However, one of the most common and most frequently used is HTTP.
HTTP is a way in which two devices can communicate, often through a network such as the Internet. Messages are sent out and received by a server. The server then responds with another message. Data can be transferred via HTTP and is used to provide data from a server to a local app, and vice versa.
If we want to send an HTTP message, we can make use of the HttpClient
property provided by .NET. To request data from a server, all we have to do is request it via the GetStringAsync()
method, passing the URI of the resource. There are other types that can be received easily, such as byte arrays via the GetByteArrayAsync()
method or a Stream
instance via the GetStreamAsync()
method. If we want more control over how the request is sent and handled, we can use the GetAsync()
method. We can then process the result of these methods using a serializer or parser.
If we want to send data to the server, we have several other methods such as the PostAsync()
method or the PutAsync()
method. These methods take both the URI and the content that needs to be sent. We typically use POST to send data to the server, but some servers handle PUT messages differently, which we may want. We may want the server to do something different when using PUT.
The content sent to the server is wrapped in an HttpContent
type. This type contains the various headers as well as the actual body that we want to send to the server. Headers are used to describe the content as well as how to handle the request. A header can include the content type, content length, or any authorization requirements. The body is the data that we wish to send. The body could be anything, but in most cases, we would serialize the data and send it. We have to be sure that we send the data in a format that the server can understand, for example in XML or JSON.
Once the server has received our message, whether through GET or POST, it will respond with a code specifying whether there were errors or not. We can then use this code and respond to the user accordingly.
It is important to remember that sending data over the network is very slow compared to normal CPU operations. Thus, to avoid any app performance issues, we carry out network operations on a separate thread. This is very easy to do with the async
and await
keywords in C#. The compiler will automatically rewrite our code to start a new thread.
As transferring data wirelessly requires battery, and possibly mobile data, it is important that we try and cache what we can. Caching will reduce the need for communication, thus reducing the load on the battery as well as the amount of data consumed.
Another battery-saving technique is prefetching. Prefetching requests data before it is actually needed to reduce the number of requests it has to make later. Each time the wireless controller is woken up, battery is consumed to restore the controller. If we bundle all our requests into a single request, the controller only has to be woken once instead of multiple times.