Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / XAML

Consume Webservice in Windows Universal App

5.00/5 (3 votes)
24 Mar 2016CPOL1 min read 11.8K   144  
In this article, we will learn how to consume Webservice in Windows Universal App

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.

Image 1

Install Json.Net in both the projects (Windows and Windows Phone) from Nuget. It will be used for serialization and deserialization of json.

Image 2

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.

C#
//Global class in shared project
 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 enums for method name and method type.

C#
//enums in shared project
  public enum WebMethod
    {
        citiesJSON=1
    }

    public enum MethodType
    {
        GET = 1,
        POST = 2
    }

Step 3

Create Utility class that will create different types of Uri.

C#
//Utility Class in shared project
public class Utility
    {
        /// <summary>
        /// Create html Url with parameters
        /// </summary>
        /// <param name="rawUrl"></param>
        /// <param name="webModule"></param>
        /// <param name="webMethod"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        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());
        }//CreateUri

        /// <summary>
        /// Create html Url without parameters
        /// </summary>
        /// <param name="rawUrl"></param>
        /// <param name="webModule"></param>
        /// <param name="webMethod"></param>
        /// <returns></returns>
        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());
        }//CreateUri

        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());
        }//CreateUri

        /// <summary>
        /// Create html Url for parameters
        /// </summary>
        /// <param name="rawUrl"></param>
        /// <param name="webModule"></param>
        /// <param name="webMethod"></param>
        /// <returns></returns>
        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();
        }//CreateUriParameter

        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.

C#
//NetworkHandler class in shared project
 public class NetworkHandler
    {
        async public static Task<string> 
        PostHtmlContent(WebMethod webMethod, object requestObj, 
        Encoding encoding, string contentType)
        {
            //Initialize WebClient
            HttpClient httpClient = new HttpClient();
            //Call service
            HttpResponseMessage response = await httpClient.PostAsync
            ((Utilities.Utility.CreateUri(Global.Global.RawUrl, webMethod)), 
            new StringContent(Utilities.Utility.CreateUriParameter(requestObj), encoding, contentType));
            //Read response
            string responseText = await response.Content.ReadAsStringAsync();
            //Return result
            return responseText;
        }

        async public static Task<string> GetHtmlContentByUrl(string url)
        {
            //Initialize WebClient
            HttpClient httpClient = new HttpClient();
            //Call service
            HttpResponseMessage response = await httpClient.GetAsync(new Uri(url));
            //Read response
            string responseText = await response.Content.ReadAsStringAsync();
            //Return result
            return responseText;
        }

        async public static Task<string> 
        GetHtmlContent(WebMethod webMethod, object requestObj,string contentType)
        {
            //Initialize WebClient
            HttpClient httpClient = new HttpClient();
            //Call service
            HttpResponseMessage response = await httpClient.GetAsync
            (Utilities.Utility.CreateUri(Global.Global.RawUrl,webMethod,requestObj));
            //Read response
            string responseText = await response.Content.ReadAsStringAsync();
            //Return result
            return responseText;
        }

        async public static Task<string> PostJsonContent
        (WebMethod webMethod, object requestObj, Encoding encoding, string contentType)
        {
            //Initialize WebClient
            HttpClient httpClient = new HttpClient();
            //Call service
            HttpResponseMessage response = await httpClient.PostAsync
            ((Utilities.Utility.CreateUri(Global.Global.RawUrl, webMethod)), 
            new StringContent(JsonConvert.SerializeObject(requestObj), encoding, contentType));
            //Read response
            string responseText = await response.Content.ReadAsStringAsync();
            //Return result
            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

C#
//GetCityRequestViewModel class in shared project
      
 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.

C#
{"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

Image 3

So, response class will be like below:

C#
//GetCityResponseViewModel class in shared project
      
    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.

C#
//MainPage.Cs
      
    protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            //Call Webservice method
            this.CallWebService(new GetCityRequestViewModel
            {
                north = "44.1",
                south = "-9.9",
                east = "-22.4",
                west = "55.2",
                lang = "de",
                username = "username"
            });
        }

        /// <summary>
        /// calling webservice
        /// </summary>
        /// <param name="obj"></param>
        private async void CallWebService(object obj)
        {
            try
            {
                string responseText = await NetworkHandler.GetHtmlContent
                (WebMethod.citiesJSON, obj, Global.Global.HtmlContentType);

                //Initialize response view Model
                GetCityResponseViewModel responseViewModel = new GetCityResponseViewModel();

                responseViewModel = JsonConvert.DeserializeObject<GetCityResponseViewModel>(responseText);
            }
            catch (Exception ex)
            {
            }
            finally
            {
            }

        }//CallWebService

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)