مسئله
نحوه مصرف ASP.NET Core Web API با استفاده از HttpClient.
راه حل
ما یک کتابخانه برای بسته بندی عملکرد HttpClient ایجاد خواهیم کرد. من از الگوی سازنده برای این منظور استفاده خواهم کرد. یک کلاس با متدهایی برای ذخیره قطعات HttpClient اضافه کنید.
- public class HttpRequestBuilder
- {
- private HttpMethod method = null;
- private string requestUri = "";
- private HttpContent content = null;
- private string bearerToken = "";
- private string acceptHeader = "application/json";
- private TimeSpan timeout = new TimeSpan(0, 0, 15);
- public HttpRequestBuilder()
- {
- }
- public HttpRequestBuilder AddMethod(HttpMethod method)
- {
- this.method = method;
- return this;
- }
- public HttpRequestBuilder AddRequestUri(string requestUri)
- {
- this.requestUri = requestUri;
- return this;
- }
- public HttpRequestBuilder AddContent(HttpContent content)
- {
- this.content = content;
- return this;
- }
- public HttpRequestBuilder AddBearerToken(string bearerToken)
- {
- this.bearerToken = bearerToken;
- return this;
- }
- public HttpRequestBuilder AddAcceptHeader(string acceptHeader)
- {
- this.acceptHeader = acceptHeader;
- return this;
- }
- public HttpRequestBuilder AddTimeout(TimeSpan timeout)
- {
- this.timeout = timeout;
- return this;
- }
- rest of code
روشی برای ارسال درخواست با استفاده از HttpClient اضافه کنید و پاسخ را دریافت کنید.
- public async Task<HttpResponseMessage> SendAsync()
- {
- // Check required arguments
- EnsureArguments();
- // Setup request
- var request = new HttpRequestMessage
- {
- Method = this.method,
- RequestUri = new Uri(this.requestUri)
- };
- if (this.content != null)
- request.Content = this.content;
- if (!string.IsNullOrEmpty(this.bearerToken))
- request.Headers.Authorization =
- new AuthenticationHeaderValue("Bearer", this.bearerToken);
- request.Headers.Accept.Clear();
- if (!string.IsNullOrEmpty(this.acceptHeader))
- request.Headers.Accept.Add(
- new MediaTypeWithQualityHeaderValue(this.acceptHeader));
- // Setup client
- var client = new System.Net.Http.HttpClient();
- client.Timeout = this.timeout;
- return await client.SendAsync(request);
- }
همچنین یک کلاس کارخانه برای ایجاد درخواستهای GET، POST، PUT، PATCH و DELETE اضافه میکنیم.
- public static class HttpRequestFactory
- {
- public static async Task<HttpResponseMessage> Get(string requestUri)
- {
- var builder = new HttpRequestBuilder()
- .AddMethod(HttpMethod.Get)
- .AddRequestUri(requestUri);
- return await builder.SendAsync();
- }
- public static async Task<HttpResponseMessage> Post(
- string requestUri, object value)
- {
- var builder = new HttpRequestBuilder()
- .AddMethod(HttpMethod.Post)
- .AddRequestUri(requestUri)
- .AddContent(new JsonContent(value)) ;
- return await builder.SendAsync();
- }
- public static async Task<HttpResponseMessage> Put(
- string requestUri, object value)
- {
- var builder = new HttpRequestBuilder()
- .AddMethod(HttpMethod.Put)
- .AddRequestUri(requestUri)
- .AddContent(new JsonContent(value));
- return await builder.SendAsync();
- }
- public static async Task<HttpResponseMessage> Patch(
- string requestUri, object value)
- {
- var builder = new HttpRequestBuilder()
- .AddMethod(new HttpMethod("PATCH"))
- .AddRequestUri(requestUri)
- .AddContent(new PatchContent(value));
- return await builder.SendAsync();
- }
- public static async Task<HttpResponseMessage> Delete(string requestUri)
- {
- var builder = new HttpRequestBuilder()
- .AddMethod(HttpMethod.Delete)
- .AddRequestUri(requestUri);
- return await builder.SendAsync();
- }
- }
JsonContent، PatchContent و FileContent کلاس های سفارشی برای ساده سازی ارسال داده ها هستند.
- public class JsonContent : StringContent
- {
- public JsonContent(object value)
- : base (JsonConvert.SerializeObject(value), Encoding.UTF8, "application/json")
- {
- }
- public JsonContent(object value, string mediaType)
- : base(JsonConvert.SerializeObject(value), Encoding.UTF8, mediaType)
- {
- }
- }
- public class PatchContent : StringContent
- {
- public PatchContent(object value)
- : base (JsonConvert.SerializeObject(value), Encoding.UTF8,
- "application/json-patch+json")
- {
- }
- }
- public class FileContent : MultipartFormDataContent
- {
- public FileContent(string filePath, string apiParamName)
- {
- var filestream = File.Open(filePath, FileMode.Open);
- var filename = Path.GetFileName(filePath);
- Add(new StreamContent(filestream), apiParamName, filename);
- }
- }
در نهایت، چند روش افزودنی برای کمک به کار با کلاس HttpResponseMessage.
- public static class HttpResponseExtensions
- {
- public static T ContentAsType<T>(this HttpResponseMessage response)
- {
- var data = response.Content.ReadAsStringAsync().Result;
- return string.IsNullOrEmpty(data) ?
- default(T) :
- JsonConvert.DeserializeObject<T>(data);
- }
- public static string ContentAsJson(this HttpResponseMessage response)
- {
- var data = response.Content.ReadAsStringAsync().Result;
- return JsonConvert.SerializeObject(data);
- }
- public static string ContentAsString(this HttpResponseMessage response)
- {
- return response.Content.ReadAsStringAsync().Result;
- }
- }
ما می توانیم از کد بالا استفاده کنیم مانند -
- private static async Task GetList()
- {
- var requestUri = $"{baseUri}";
- var response = await HttpRequestFactory.Get(requestUri);
- Console.WriteLine($"Status: {response.StatusCode}");
- var outputModel = response.ContentAsType<List<MovieOutputModel>>();
- outputModel.ForEach(item =>
- Console.WriteLine("{0} - {1}", item.Id, item.Title));
- }
در اینجا نحوه ظاهر مشتری نمونه است.
توجه داشته باشید
کد نمونه نمونه هایی از نوع دیگری از درخواست ها را نیز دارد. از CRUD API ایجاد شده در پست قبلی استفاده می کند . پروژه آن را دانلود کنید و قبل از اجرای این نمونه کنسول، API را اجرا کنید.
کد منبع