اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
چهار دقیقه
در این قسمت میخواهیم با Rest Api ارتباط برقرار کنیم. به جای نوشتن سمت سرور، از یک سرور آماده استفاده میکنیم که مثال اول آن، LIST USERS است و لیست کاربران را نمایش میدهد. توضیحات این قسمت به فراخوانی سرویسهای Rest ارتباط دارد، با پروتکل HTTP و دیتای JSON. البته فراخوانی سرویسهای SOAP نیز ساده است که در این آموزش به آنها نمیپردازیم.
برای این کار از HttpClient استفاده میکنیم. استفاده کردن از WebClient و WebRequest اشتباه محض هست و این دو را کلا فراموش کنید. مطمئن باشید هر کدی که با آن دو در اینترنت پیدا میکنید، با HttpClient هم قابلیت پیاده سازی را دارند و مطمئن باشید که اگر از آن دو کلاس استفاده کنید، حتما به دردسر بدی میافتید. در زمان استفاده از HttpClient هم در نظر بگیرید که نباید مدام HttpClient را new و dispose کنید. این کار اشتباه است و یک HTTP client برای شما کافی است. ساختن HTTP client نکات بسیاری دارد که در همین سایت به آنها پرداخته شدهاست. در Xamarin دغدغههای استفاده از Network Stack هر سیستم عامل نیز به لیست مواردی که باید به آنها دقت کنید اضافه میشوند. میتوانید درگیر تمامی این موارد شوید، یا برای سادگی بیشتر، ضمن نصب پکیج Bit.CSharpClient.Rest که کدهای آن نیز در GitHub قرار داده شدهاند، صرفا HTTP Client را بگیرید و به هر جایی که دوست دارید Request بزنید. لزومی به اینکه در سمت سرور از Bit استفاده کرده باشید تا بتوانید از Bit.CSharpClient.Rest استفاده کنید نیست.
خب، پس Package مربوطه را نصب و در App.xaml.cs کدهای زیر را استفاده کنید:
//قرار دهید containerBuilder.RegisterRequiredServices(); این دو را بعد از containerBuilder.RegisterHttpClient(); containerBuilder.RegisterIdentityClient();
در View Model ای که قصد استفاده از Http Client را دارید، یک Property از جنس Http Client تعریف کنید و برای خواندن اطلاعات مثال، کد زیر را بزنید:
توضیحات این کد در ادامه آمده است.
توضیحات این کد در ادامه آمده است.
public virtual HttpClient HttpClient { get; set; } async Task CallUsersListApiUsingHttpClient() { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://reqres.in/api/users"); // Use request.Headers to set jwt token, ... // Use request.Content to send body. You can use StringContent, StreamContent, etc. HttpResponseMessage response = await HttpClient.SendAsync(request); response.EnsureSuccessStatusCode(); using (StreamReader streamReader = new StreamReader(await response.Content.ReadAsStreamAsync())) using (JsonReader jsonReader = new JsonTextReader(streamReader)) { List<UserDto> users = (await JToken.LoadAsync(jsonReader))["data"].ToObject<List<UserDto>>(); } }
{ "page": 2, "per_page": 3, "total": 12, "total_pages": 4, "data": [ { "id": 4, "first_name": "Eve", "last_name": "Holt", "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg" }, { "id": 5, "first_name": "Charles", "last_name": "Morris", "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg" } ] }
قسمتهای مختلف این JSON برای ما اهمیتی ندارند و تنها قسمت data آن که اطلاعات userها را شامل میشود، برای ما اهمیت دارند. صد البته که هر سروری، دیتای JSON را با ساختاری که دوست داشته باشد بر میگرداند. در کدی که نوشتهایم، ابتدا یک HttpRequestMessage را ساختهایم. این HttpRequestMessage از نوع Get و به آدرس https://reqres.in/api/users است. میتوان روی HttpRequestMessage هم هدرهای مختلفی را تنظیم نمود و هم میتوان به آن Content داد.
سپس آن را با HttpClient.SendAsync ارسال میکنیم و با فراخوانی EnsureSuccessStatusCode مطمئن میشویم که خطا ندادهاست. برای خواندن Response با بالاترین Performance ممکن، ابتدا از StreamReader برای خواندن Stream دریافتی استفاده میکنیم. با توجه به JSON بودن Response دریافتی، از JsonTextReader و JToken استفاده میکنیم (این مورد هیچ ربطی به JWT یا Json Web Token ندارد!). بعد از Load کردن آن، قسمت ["data"] را به لیستی از کلاس UserDto تبدیل میکنیم. Dto مخفف Data Transfer Object است و دیتایی است که ما یا ارسال میکنیم یا در همین سناریو مثال، از سرور دریافت میکنیم. کد کلاس UserDto:
public class UserDto { [JsonProperty("id")] public int Id { get; set; } [JsonProperty("first_name")] public string FirstName { get; set; } [JsonProperty("last_name")] public string LastName { get; set; } [JsonProperty("avatar")] public string Avatar { get; set; } }