【6月日新计划15】WPF入门-呼叫Api

337 阅读3分钟

【6月日新计划15】WPF入门-呼叫Api

1. OpenWeather

可免費使用的天氣api => home.openweathermap.org/

图片.png

1.註冊賬號

使用郵箱註冊。

2.獲取key

图片.png

3.點擊導航欄Api,選擇當前天氣

图片.png

图片.png

4.測試Api

  • 1.使用經緯度坐標

    https://api.openweathermap.org/data/2.5/weather?lat=xxx&lon=xxx&appid=xxxx

    Example : =>https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid=xxxx

  • 2.使用城市名

    https://api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}

Example : =>https://api.openweathermap.org/data/2.5/weather?q=London&appid=xxxx

  • 3.Response format
默認Josn
https://api.openweathermap.org/data/2.5/weather?q=London&appid={APIkey}
https://api.openweathermap.org/data/2.5/weather?q=London&mode=xml

2. Debug

  • 顯示到命令提示符的黑窗口

    Console.WriteLine("输出信息");

  • 打印到輸出窗口

    System.Diagnostics.Debug.WriteLine("输出信息"); System.Diagnostics.Trace.WriteLine("输出信息");

3. Client Call Api

3.1 Create Service

把一些公用方法提取出來

1.封裝請求

namespace BlankApp1.Service
{
    public class BaseRequest
    {
        /// <summary>
        /// 請求方法
        /// </summary>
        public Method Method { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Route { get; set; }
        
        /// <summary>
        ///header 請求頭 
        /// </summary>
        public string ContentType { get; set; } = "application/json";

        /// <summary>
        /// Body裡面的參數
        /// </summary>
        public object Parameter { get; set; }
    }
}

2.封裝client,RestSharp version 106.12.0

namespace BlankApp1.Service
{
    public class HttpRestClient
    {

        private readonly string url;

        protected readonly RestClient client;

        public HttpRestClient(string url)
        {

            this.url = url;
            client = new RestClient(url);
        }
        
                public async Task<T> ExecuteAsync<T>(BaseRequest baseRequest)
        {
            var request = new RestRequest(baseRequest.Method);
            request.AddHeader("Content-Type", baseRequest.ContentType);

            if (baseRequest.Parameter != null)
            {
                request.AddParameter("param", JsonConvert.SerializeObject(baseRequest.Parameter), ParameterType.RequestBody);
            }

            client.BaseUrl = new Uri(url + baseRequest.Route);
            var response = await client.ExecuteAsync(request);

            System.Diagnostics.Trace.WriteLine("---------Client執行結果 :" + response.Content);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                System.Diagnostics.Trace.WriteLine("---------將結果封裝---------------");
                return JsonConvert.DeserializeObject<T> (response.Content);
            }
            else
                return default(T);
        }

        public string ExecuteAsync01<T>(BaseRequest baseRequest)
        {
            var request = new RestRequest(baseRequest.Method);
            request.AddHeader("Content-Type", baseRequest.ContentType);

            if (baseRequest.Parameter != null)
            {
                request.AddParameter("param", JsonConvert.SerializeObject(baseRequest.Parameter), ParameterType.RequestBody);
            }

            client.BaseUrl = new Uri(url + baseRequest.Route);
            var response = await client.ExecuteAsync(request);
            
            var result = response.Result.Content;
            return result;
        }
    }
}

3.使用接口,封裝請求

namespace BlankApp1.Service
{
    public interface IBaseService<TEntity> where TEntity : class
    {
        Task<TEntity> AddAsync(TEntity entity);

        Task<TEntity> UpdateAsync(TEntity entity);

        Task<TEntity> DeleteAsync(int id);

        Task<TEntity> GetFirstOfDefaultAsync(int id);

        Task<TEntity> GetWeatherAsync(WeatherParameter parameter);

        Task<TEntity> GetCurrentWeatherAsync(WeatherParameter parameter);
    }
}
namespace BlankApp1.Service
{
    public class BaseService<TEntity> : IBaseService<TEntity> where TEntity : class
    {
        private readonly HttpRestClient client;
        private readonly string serviceName;

        public BaseService(HttpRestClient client, string serviceName)
        {
            this.client = client;
            this.serviceName = serviceName;
        }

        public async Task<TEntity> AddAsync(TEntity entity)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.POST;
            request.Route = $"api/{serviceName}/Add";
            request.Parameter = entity;
            return await client.ExecuteAsync<TEntity>(request);
        }

        public async Task<TEntity> DeleteAsync(int id)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.DELETE;
            request.Route = $"api/{serviceName}/Delete?id={id}";
            return await client.ExecuteAsync<TEntity>(request);
        }


        public async Task<TEntity> GetWeatherAsync(WeatherParameter parameter)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.GET;
            System.Diagnostics.Trace.WriteLine("---------输出信息:" + request.Method);
            request.Route = $"data/2.5/forecast?q={parameter.Query}" +
                $"&appid={parameter.AppId}";
            System.Diagnostics.Trace.WriteLine("---------输出信息:" + request.Route);
            return await client.ExecuteAsync<TEntity>(request);
        }

        public async Task<TEntity> GetFirstOfDefaultAsync(int id)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.GET;
            
            request.Route = $"api/{serviceName}/Get?id={id}";
            return await client.ExecuteAsync<TEntity>(request);
        }

        public async Task<TEntity> UpdateAsync(TEntity entity)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.POST;
            request.Route = $"api/{serviceName}/Update";
            request.Parameter = entity;
            return await client.ExecuteAsync<TEntity>(request);
        }

        public async Task<TEntity> GetCurrentWeatherAsync(WeatherParameter parameter)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.GET;
            request.Route = $"data/2.5/weather?q={parameter.Query}" +
                $"&appid={parameter.AppId}";
            System.Diagnostics.Trace.WriteLine("---------输出信息:" + request.Route);
            return await client.ExecuteAsync<TEntity>(request);
        }
    }
}
namespace BlankApp1.Service
{
    public interface IWeatherService : IBaseService<CurrentWeather>
    {

        string GetCurrentWeather2(WeatherParameter parameter);

        string GetCurrentWeather3(WeatherParameter parameter);
    }
}
namespace BlankApp1.Service
{
    public class WeatherService : BaseService<Weather>, IWeatherService
    {
        private readonly HttpRestClient client;
        public WeatherService(HttpRestClient client) : base(client, "Weather")
        {
            this.client = client;
        }


        public string GetCurrentWeather3(WeatherParameter parameter)
        {

            var client = new RestClient();
            string url = "https://api.openweathermap.org/data/2.5/weather?q=DongGuan&appid=a6a233d819314226c367fe3c3778af8b";
            client.BaseUrl = new Uri(url);

            var request = new RestRequest();
            request.Method = RestSharp.Method.GET;
            Task<IRestResponse> response = client.ExecuteAsync(request);
            return response.Result.Content;
        }

        public string GetCurrentWeather2(WeatherParameter parameter)
        {
            System.Diagnostics.Trace.WriteLine("---------输出信息:開始執行");
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.GET;
            request.Route = $"data/2.5/weather?q={parameter.Query}" +
                $"&appid={parameter.AppId}";
            System.Diagnostics.Trace.WriteLine("---------Route Msg:" + request.Route);
            return client.ExecuteAsync01<CurrentWeather>(request);
        }

        async Task<CurrentWeather> IBaseService<CurrentWeather>.GetCurrentWeatherAsync(WeatherParameter parameter)
        {
            System.Diagnostics.Trace.WriteLine("---------输出信息:開始執行");
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.GET;
            request.Route = $"data/2.5/weather?q={parameter.Query}" +
                $"&appid={parameter.AppId}";
            System.Diagnostics.Trace.WriteLine("---------Route Msg:" + request.Route);
            return await client.ExecuteAsync<CurrentWeather>(request);
        }

    }
}
namespace BlankApp1.ViewModels.Config
{
    class WeatherViewModel
    {
        private readonly IWeatherService _weatherService;
        public WeatherViewModel(IWeatherService weatherService)
        {
            this._weatherService = weatherService;
            queryWeathers();
        }

        public void queryWeathers()
        {
            var response = _weatherService.GetCurrentWeather2(new WeatherParameter() { Query = "DongGuan" });
            CurrentWeather currentWeather = JsonConvert.DeserializeObject<CurrentWeather>(response);

            var result = currentWeather.GetType().GetProperty("Weather").GetValue(currentWeather, null);
            ObservableCollection<WeatherDto01> weather001 = (ObservableCollection<WeatherDto01>)result;
            foreach (var item in weather001)
            {
                System.Diagnostics.Trace.WriteLine("---------查看結果:" + item.GetType().GetProperty("Main").GetValue(item, null));
            }
        }
    }
}

route就參考自己的後端api

namespace BlankApp1.Service
{
    public class BaseService<TEntity> : IBaseService<TEntity> where TEntity : class
    {
        private readonly HttpRestClient client;
        private readonly string serviceName;

        public BaseService(HttpRestClient client, string serviceName)
        {
            this.client = client;
            this.serviceName = serviceName;
        }

        public async Task<ApiResponse<TEntity>> AddAsync(TEntity entity)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.POST;
            request.Route = $"api/{serviceName}/Add";
            request.Parameter = entity;
            return await client.ExecuteAsync<TEntity>(request);
        }

        public async Task<ApiResponse> DeleteAsync(int id)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.DELETE;
            request.Route = $"api/{serviceName}/Delete?id={id}";
            return await client.ExecuteAsync(request);
        }

        public async Task<ApiResponse<PagedList<TEntity>>> GetAllAsync(QueryParameter parameter)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.GET;
            request.Route = $"api/{serviceName}/GetAll?pageIndex={parameter.PageIndex}" +
                $"&pageSize={parameter.PageSize}" +
                $"&search={parameter.Search}";
            return await client.ExecuteAsync<PagedList<TEntity>>(request);
        }

        public string GetWeatherAsync<TEntity>(WeatherParameter parameter)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.GET;
            System.Diagnostics.Trace.WriteLine("---------输出信息:" + request.Method);
            request.Route = $"data/2.5/forecast?q={parameter.Query}" +
                $"&appid={parameter.AppId}";
            System.Diagnostics.Trace.WriteLine("---------输出信息:" + request.Route);
            return client.ExecuteAsync<TEntity>(request);
        }

        public async Task<ApiResponse<TEntity>> GetFirstOfDefaultAsync(int id)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.GET;
            
            request.Route = $"api/{serviceName}/Get?id={id}";
            return await client.ExecuteAsync<TEntity>(request);
        }

        public async Task<ApiResponse<TEntity>> UpdateAsync(TEntity entity)
        {
            BaseRequest request = new BaseRequest();
            request.Method = RestSharp.Method.POST;
            request.Route = $"api/{serviceName}/Update";
            request.Parameter = entity;
            return await client.ExecuteAsync<TEntity>(request);
        }
    }
}

3.2 App.xaml register

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //將host進行註冊,這個url對應前面封裝的client裡面的url
            containerRegistry.GetContainer().Register<HttpRestClient>(made: Parameters.Of.Type<string>(serviceKey: "url"));
            containerRegistry.GetContainer().RegisterInstance(@"https://api.openweathermap.org", serviceKey: "url");

            //將呼叫方法的service進行註冊
            containerRegistry.Register<IWeatherService, WeatherService>();

            //將view和viewModel捆綁,已經註冊。
            containerRegistry.RegisterForNavigation<ToDoView,ToDoViewModel>();
            containerRegistry.RegisterForNavigation<OlkView,OLKViewModel>();
            containerRegistry.RegisterForNavigation<IndexView,IndexViewModel>();
            containerRegistry.RegisterForNavigation<ConfigView,ConfigViewModel>();

            containerRegistry.RegisterForNavigation<SettingView,SettingViewModel>();
            containerRegistry.RegisterForNavigation<SecurityView, SecurityViewModel>();
            containerRegistry.RegisterForNavigation<CustomView, CustomViewModel>();
            containerRegistry.RegisterForNavigation<WeatherView, WeatherViewModel>();
            containerRegistry.RegisterForNavigation<MessageView, MessageViewModel>();
        }

3.3 View And ViewModel

  • View就是某個功能的頁面
  • ViewModel這個頁面的一些簡單的功能和要顯示的數據的定義
  • 具體的方法,來操作上面的數據。

1.View

namespace BlankApp1.Common.Models.Config
{
    public class ItemsDto
    {
		private string value;

		public string Value
		{
			get { return value; }
			set { this.value = value; }
		}

		private string html;

		public string Html
		{
			get { return html; }
			set { html = value; }
		}

		private string label;

		public string Label
		{
			get { return label; }
			set { label = value; }
		}


	}
}

2.ViewModel

namespace BlankApp1.ViewModels.Config
{
    public class DataViewModel : BindableBase
    {

        private ObservableCollection<ItemsDto> collectionData;

        public ObservableCollection<ItemsDto> CollectionData
        {
            get { return collectionData; }
            set { collectionData = value; RaisePropertyChanged(); }
        }

        private readonly IDataService dataService;
        public DataViewModel(DataService dataService) { 
        
            this.dataService = dataService;
            collectionData = new ObservableCollection<ItemsDto>();
            GetMsg();
        }

        public void GetMsg() {

            var result = dataService.GetData();
            foreach (var item in result)
            {
                collectionData.Add(item);
            }
        }
    }
}
namespace BlankApp1.Service.Config
{
    public class DataService : BaseService<DataDto>, IDataService
    {


        private readonly HttpRestClient client;
        public DataService(HttpRestClient client) : base(client, "Data")
        {
            this.client = client;
        }

        public ObservableCollection<ItemsDto> GetData()
        {

            var client = new RestClient();
            string url = "http://xxxxxe";
            client.BaseUrl = new Uri(url);

            var request = new RestRequest();
            request.Method = RestSharp.Method.GET;

            Task<IRestResponse<DataDto>> response = client.ExecuteAsync<DataDto>(request);
            System.Diagnostics.Trace.WriteLine("---------输出信息:" + response.Result.Content);

            //返回的結果
            ObservableCollection<ItemsDto> itemsDtosResult = new ObservableCollection<ItemsDto>();

            //解析數據
            DataDto dataDto = (DataDto)JsonConvert.DeserializeObject<DataDto>(response.Result.Content);
            var list = dataDto.GetType().GetProperties();
            foreach (var property in list)
            {
                var value = property.GetValue(dataDto, null);
                System.Diagnostics.Trace.WriteLine("---------成員信息:" + value);
                if(property.Name.Equals("Items")){

                    
                    ObservableCollection<ItemsDto> collection = 
                        (ObservableCollection<ItemsDto>) value;
                    foreach (var item in collection)
                    {
                        itemsDtosResult.Add(item);
                        System.Diagnostics.Trace.WriteLine("---------成員信息:" + item.GetType().GetProperty("Value").GetValue(item,null));
                    }
                }
            }

            return itemsDtosResult;
        }
    }
}