Introduction
Whenever you want your app to communicate with network or get/post data from network, you need to consume Webservice. So, we will see here how to use rest webservice in Windows Universal App.
Description
Take a new project, i.e., Blank App (Universal Apps) and give it a name whatever you want.
When you will see in Solution Explorer, you will find three types of projects here - Windows store app, Windows phone app and Shared project. Here, we are sharing code but not the design so we will create design individually for each type of app in XAML.
Install Json.Net in both the projects (Windows and Windows Phone) from Nuget. It will be used for serialization and deserialization of json.
Now, we will see the step by step by process to consume rest webservice in a professional manner.
Step 1
Create Global
class in shared project that will contain all the global variables.
public class Global
{
public const string RawUrl = "http://api.geonames.org/";
public const string JsonContentType = "application/json";
public const string HtmlContentType = "application/x-www-form-urlencoded";
}
Step 2
Create enum
s for method name and method type.
public enum WebMethod
{
citiesJSON=1
}
public enum MethodType
{
GET = 1,
POST = 2
}
Step 3
Create Utility
class that will create different types of Uri
.
public class Utility
{
public static Uri CreateUri(string rawUrl, Enumerations.WebMethod webMethod, object obj)
{
StringBuilder sb = new StringBuilder();
sb.Append(rawUrl);
sb.Append("/");
sb.Append(webMethod.ToString());
sb.Append("?");
Type t = obj.GetType();
PropertyInfo[] props = t.GetRuntimeProperties().ToArray();
foreach (PropertyInfo prp in props)
{
if (prp.GetValue(obj) != null)
{
sb.Append(prp.Name);
sb.Append("=");
sb.Append(prp.GetValue(obj).ToString());
sb.Append("&");
}
}
return new Uri(sb.ToString());
}
public static Uri CreateUri(string rawUrl, Enumerations.WebMethod webMethod)
{
StringBuilder sb = new StringBuilder();
sb.Append(rawUrl);
sb.Append("/");
sb.Append(webMethod.ToString());
return new Uri(sb.ToString());
}
public static Uri CreateUri(string rawUrl, Enumerations.WebMethod webMethod, string parameter)
{
StringBuilder sb = new StringBuilder();
sb.Append(rawUrl);
sb.Append("/");
sb.Append(webMethod.ToString());
sb.Append("/");
sb.Append(parameter);
return new Uri(sb.ToString());
}
public static string CreateUriParameter(Object obj)
{
StringBuilder sb = new StringBuilder();
Type t = obj.GetType();
PropertyInfo[] props = t.GetRuntimeProperties().ToArray();
foreach (PropertyInfo prp in props)
{
if (prp.GetValue(obj) != null)
{
sb.Append(prp.Name);
sb.Append("=");
sb.Append(prp.GetValue(obj).ToString());
sb.Append("&");
}
}
return sb.ToString();
}
public static string CreateHtmlPostData(object obj)
{
StringBuilder sb = new StringBuilder();
Type t = obj.GetType();
PropertyInfo[] props = t.GetRuntimeProperties().ToArray();
foreach (PropertyInfo prp in props)
{
if (prp.GetValue(obj) != null)
{
sb.Append("&");
sb.Append(prp.Name);
sb.Append("=");
sb.Append(prp.GetValue(obj).ToString());
}
}
return sb.ToString();
}
}
Step 4
Create Network Handler class that will contain methods to call webservice.
public class NetworkHandler
{
async public static Task<string>
PostHtmlContent(WebMethod webMethod, object requestObj,
Encoding encoding, string contentType)
{
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.PostAsync
((Utilities.Utility.CreateUri(Global.Global.RawUrl, webMethod)),
new StringContent(Utilities.Utility.CreateUriParameter(requestObj), encoding, contentType));
string responseText = await response.Content.ReadAsStringAsync();
return responseText;
}
async public static Task<string> GetHtmlContentByUrl(string url)
{
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.GetAsync(new Uri(url));
string responseText = await response.Content.ReadAsStringAsync();
return responseText;
}
async public static Task<string>
GetHtmlContent(WebMethod webMethod, object requestObj,string contentType)
{
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.GetAsync
(Utilities.Utility.CreateUri(Global.Global.RawUrl,webMethod,requestObj));
string responseText = await response.Content.ReadAsStringAsync();
return responseText;
}
async public static Task<string> PostJsonContent
(WebMethod webMethod, object requestObj, Encoding encoding, string contentType)
{
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.PostAsync
((Utilities.Utility.CreateUri(Global.Global.RawUrl, webMethod)),
new StringContent(JsonConvert.SerializeObject(requestObj), encoding, contentType));
string responseText = await response.Content.ReadAsStringAsync();
return responseText;
}
}
Step 5
Create ViewModel
classes for request and response.
Request
Request is in Html format, so we will create class for its request parameters.
http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo
public class GetCityRequestViewModel
{
public string north { get; set; }
public string south { get; set; }
public string east { get; set; }
public string west { get; set; }
public string lang { get; set; }
public string username { get; set; }
}
Response
Response is in json format, so we will create class for its response parameters.
{"geonames":[{"lng":-99.12766456604,"geonameId":3530597,
"countrycode":"MX","name":"Mexiko-Stadt",
"fclName":"city, village,...","toponymName":"Mexico City",
"fcodeName":"capital of a political entity",
"wikipedia":"en.wikipedia.org/wiki/Mexico_City","lat":19.428472427036,
"fcl":"P","population":12294193,"fcode":"PPLC"},
{"lng":116.397228240967,"geonameId":1816670,"countrycode":"CN",
"name":"Peking","fclName":"city, village,...",
"toponymName":"Beijing","fcodeName":"capital of a political entity",
"wikipedia":"en.wikipedia.org/wiki/Beijing","lat":39.9074977414405,
"fcl":"P","population":11716620,"fcode":"PPLC"},
{"lng":120.9822,"geonameId":1701668,"countrycode":"PH",
"name":"Manila","fclName":"city, village,...",
"toponymName":"Manila","fcodeName":"capital of a political entity",
"wikipedia":"en.wikipedia.org/wiki/Manila","lat":14.6042,"fcl":
"P","population":10444527,"fcode":"PPLC"},
{"lng":90.40743827819824,"geonameId":1185241,"countrycode":
"BD","name":"Dhaka","fclName":"city, village,...",
"toponymName":"Dhaka","fcodeName":"capital of a political entity",
"wikipedia":"en.wikipedia.org/wiki/Dhaka","lat":23.710395616597037,
"fcl":"P","population":10356500,"fcode":"PPLC"},
{"lng":126.9784,"geonameId":1835848,"countrycode":"KR",
"name":"Seoul","fclName":"city, village,...",
"toponymName":"Seoul","fcodeName":"capital of a political entity",
"wikipedia":"en.wikipedia.org/wiki/Seoul","lat":37.566,"fcl":
"P","population":10349312,"fcode":"PPLC"},
{"lng":106.84513092041016,"geonameId":1642911,"countrycode":"ID",
"name":"Jakarta","fclName":"city, village,...",
"toponymName":"Jakarta","fcodeName":"capital of a political entity",
"wikipedia":"en.wikipedia.org/wiki/Jakarta","lat":-6.214623197035775,
"fcl":"P","population":8540121,"fcode":"PPLC"},
{"lng":139.69171,"geonameId":1850147,"countrycode":"JP",
"name":"Tokyo","fclName":"city, village,...",
"toponymName":"Tokyo","fcodeName":"capital of a political entity",
"wikipedia":"de.wikipedia.org/wiki/Tokyo","lat":35.6895,"fcl":
"P","population":8336599,"fcode":"PPLC"},
{"lng":121.531846,"geonameId":1668341,"countrycode":"TW",
"name":"Taipeh","fclName":"city, village,...",
"toponymName":"Taipei","fcodeName":"capital of a political entity",
"wikipedia":"de.wikipedia.org/wiki/Taipei","lat":25.047763,
"fcl":"P","population":7871900,"fcode":"PPLC"},
{"lng":-74.08175468444824,"geonameId":3688689,"countrycode":"CO",
"name":"Bogotá","fclName":"city, village,...",
"toponymName":"Bogotá","fcodeName":"capital of a political entity",
"wikipedia":"en.wikipedia.org/wiki/Bogot%C3%A1","lat":4.609705849789108,
"fcl":"P","population":7674366,"fcode":"PPLC"},
{"lng":114.157691001892,"geonameId":1819729,"countrycode":"HK",
"name":"Hong Kong","fclName":"city, village,...",
"toponymName":"Hong Kong","fcodeName":"capital of a political entity",
"wikipedia":"en.wikipedia.org/wiki/Hong_Kong","lat":22.2855225817732,
"fcl":"P","population":7012738,"fcode":"PPLC"}]
Generally, it is very complicated to create deserialize class for any json. So, we can use a online tool to create deserialize class for any json.
json2csharp.com
So, response class will be like below:
public class GetCityResponseViewModel
{
public List<Geoname> geonames { get; set; }
}
public class Geoname
{
public double lng { get; set; }
public int geonameId { get; set; }
public string countrycode { get; set; }
public string name { get; set; }
public string fclName { get; set; }
public string toponymName { get; set; }
public string fcodeName { get; set; }
public string wikipedia { get; set; }
public double lat { get; set; }
public string fcl { get; set; }
public int population { get; set; }
public string fcode { get; set; }
}
Step 6
Architecture is ready, now we will use it in our app page.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.CallWebService(new GetCityRequestViewModel
{
north = "44.1",
south = "-9.9",
east = "-22.4",
west = "55.2",
lang = "de",
username = "username"
});
}
private async void CallWebService(object obj)
{
try
{
string responseText = await NetworkHandler.GetHtmlContent
(WebMethod.citiesJSON, obj, Global.Global.HtmlContentType);
GetCityResponseViewModel responseViewModel = new GetCityResponseViewModel();
responseViewModel = JsonConvert.DeserializeObject<GetCityResponseViewModel>(responseText);
}
catch (Exception ex)
{
}
finally
{
}
}