در این قسمت میخواهیم با 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>>();
}
}
برای درک بهتر این کد، بعد از Clone/Pull کردن آخرین وضعیت پروژه XamApp به سراغ کلاس RestSamplesViewModel بروید. فراخوانی https://reqres.in/api/users چنین JSON ای را بر میگرداند:
{
"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; }
}
البته Http Client فقط برای ارسال یا دریافت JSON نیست. میتوان با آن فایل و Xml و ... نیز ارسال و دریافت نمود. در این قسمت مهم نبود که سرور شما با چه تکنولوژی ای توسعه داده شدهاست. صرف بودن سرور روی پروتکل Http کافی است. واضح است که شما دارید از HttpClient استفاده میکنید. در صورتیکه سرور TCP باشد، شما در CSharp میتوانید از TcpClient و Socket استفاده کنید. اگر سمت سرور شما Wcf یا OData یا Graphql باشد نیز کلاینتهای خودشان را در CSharp دارید و میتوانید در پروژهتان از تمامی آنها استفاده کنید که آموزش همه این موارد از حوصله این قسمت خارج است؛ اما در صورتیکه سمت سرور شما نیز با Bit توسعه داده شده باشد، میتوانید با روشهای خیلی بهتری به سرور خود وصل شوید که این موضوع قسمتهای بعدی آموزش است.