65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Windows 通用应用中消费 Web 服务

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2016 年 3 月 25 日

CPOL

1分钟阅读

viewsIcon

12190

downloadIcon

179

在本文中,我们将学习如何在 Windows 通用应用中调用 Web 服务。

引言

每当您希望您的应用程序与网络通信或从网络获取/发布数据时,都需要调用 Web 服务。因此,我们将在此处了解如何在 Windows 通用应用中使用 REST Web 服务。

描述

创建一个新项目,例如“空白应用(通用应用)”,并为其指定您想要的名称。

在解决方案资源管理器中查看时,您会发现这里有三种类型的项目 - Windows 应用商店应用、Windows Phone 应用和共享项目。在这里,我们共享代码但不共享设计,因此我们将为每种类型的应用在 XAML 中单独创建设计。

从 Nuget 在两个项目(Windows 和 Windows Phone)中安装 Json.Net。它将用于 JSON 的序列化和反序列化。

现在,我们将逐步了解以专业的方式调用 REST Web 服务的流程。

步骤 1

在共享项目中创建 Global 类,该类将包含所有全局变量。

//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";
    }

第二步

为方法名称和方法类型创建 enum

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

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

步骤 3

创建 Utility 类,该类将创建不同类型的 Uri

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

步骤 4

创建网络处理程序类,该类将包含调用 Web 服务的相关方法。

//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;
        }
    }

步骤 5

为请求和响应创建 ViewModel 类。

请求

请求是 HTML 格式,因此我们将为它的请求参数创建类。

http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo

//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; }
    }

响应

响应是 JSON 格式,因此我们将为它的响应参数创建类。

{"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"}]

通常,为任何 JSON 创建反序列化类非常复杂。因此,我们可以使用在线工具为任何 JSON 创建反序列化类。

json2csharp.com

因此,响应类将如下所示

//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; }
    }

步骤 6

架构已准备就绪,现在我们将将其用于我们的应用页面。

//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
© . All rights reserved.