{"id":2681,"date":"2019-10-16T19:49:51","date_gmt":"2019-10-16T18:49:51","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=2681"},"modified":"2022-11-11T17:18:44","modified_gmt":"2022-11-11T16:18:44","slug":"c-restapiclient","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/c-restapiclient\/","title":{"rendered":"C# RestApiClient"},"content":{"rendered":"\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"csharp\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">using Newtonsoft.Json;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Net;\r\nusing System.Net.Http;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace Helpers\r\n{\r\n    public class RestApiResponse&lt;T>\r\n    {\r\n        public RestApiResponse(string url, HttpResponseMessage response, TimeSpan duration, string content, T result)\r\n        {\r\n            Url = url;\r\n            Response = response;\r\n            Duration = duration;\r\n            Content = content;\r\n            Result = result;\r\n        }\r\n        public readonly string Url;\r\n        public readonly HttpResponseMessage Response;\r\n        public readonly TimeSpan Duration;\r\n        public HttpStatusCode Status => Response.StatusCode;\r\n        public bool Success => Response.IsSuccessStatusCode;\r\n        public readonly string Content;\r\n        public readonly T Result;\r\n    }\r\n\r\n    public class RequestSettings {\r\n        public RequestSettings() { }\r\n        public RequestSettings(HttpMethod method, object content = null, string contentType = \"application\/json\") {\r\n            Method = method;\r\n            Content = content;\r\n            ContentType = contentType;\r\n        }\r\n        public HttpMethod Method { get; set; } = HttpMethod.Get;\r\n        public object Content { get; set; } = null;\r\n        public string ContentType { get; set; } = \"application\/json\";\r\n        public Dictionary&lt;string, string> Headers { get; set; } = new Dictionary&lt;string, string>();\r\n        public bool ThrowOnErrorStatus { get; set; } = false;\r\n    }\r\n\r\n   public class RestApiClient\r\n    {\r\n        private const string AuthorizationHeader = \"Authorization\";\r\n        public string BearerToken { get; set; }\r\n        private static readonly HttpClientHandler _httpClientHandler = new HttpClientHandler { UseCookies = false };\r\n        private static readonly HttpClient _httpClient = new HttpClient(_httpClientHandler);\r\n        public RestApiClient(string apiAddress)\r\n        {\r\n            this.apiAddress = apiAddress;\r\n        }\r\n        private readonly string apiAddress;\r\n       \r\n        private string GetUrl(params string[] parts)\r\n        {\r\n            var partList = new List&lt;string> { apiAddress.TrimEnd('\/') };\r\n            partList.AddRange(parts.Where(part => !string.IsNullOrEmpty(part)).Select(part => part.TrimStart('\/')));\r\n            return string.Join(\"\/\", partList);\r\n        }\r\n        public async Task&lt;RestApiResponse&lt;T>> Request&lt;T>(RequestSettings requestSettings, params string[] parts)\r\n        {\r\n            var uri = GetUrl(parts);\r\n            var requestMessage = new HttpRequestMessage(requestSettings.Method, uri);\r\n            if (!string.IsNullOrEmpty(BearerToken))\r\n            {\r\n                requestMessage.Headers.Add(AuthorizationHeader, $\"Bearer {BearerToken}\");\r\n            }\r\n            foreach (var header in requestSettings.Headers)\r\n            {\r\n                requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value);\r\n            }\r\n\r\n            if (requestSettings.Content != null) { \r\n                var contentString = (requestSettings.Content is string) ? requestSettings.Content as string : JsonConvert.SerializeObject(requestSettings.Content);\r\n                if (!string.IsNullOrEmpty(contentString))\r\n                {\r\n                    requestMessage.Content = new StringContent(contentString, Encoding.UTF8, requestSettings.ContentType);\r\n                }\r\n            }\r\n            var startTime = DateTime.Now;\r\n            var responseMessage = await _httpClient.SendAsync(requestMessage);\r\n            var responseContent = await responseMessage.Content.ReadAsStringAsync();\r\n            var duration = DateTime.Now - startTime;\r\n            if (responseMessage.StatusCode == HttpStatusCode.Unauthorized)\r\n            {\r\n                throw new UnauthorizedAccessException($\"Unauthorized; Url: {uri}\");\r\n            }\r\n            else if (requestSettings.ThrowOnErrorStatus &amp;&amp; !responseMessage.IsSuccessStatusCode)\r\n            {\r\n                throw new Exception($\"[{uri}]\\r\\n[Error, status not expected: {responseMessage.StatusCode}]\\r\\n{responseContent}\");\r\n            }\r\n            if (typeof(T) != typeof(string))\r\n            {\r\n                T result = default;\r\n                try {\r\n                    result = JsonConvert.DeserializeObject&lt;T>(responseContent);\r\n                } catch (Exception) { \/* ignore *\/ }\r\n                return new RestApiResponse&lt;T>(uri, responseMessage, duration, responseContent, result);\r\n            }\r\n            \/\/ Return the request content as string\r\n            return new RestApiResponse&lt;T>(uri, responseMessage, duration, responseContent, (T)Convert.ChangeType(responseContent, typeof(T)));\r\n        }\r\n        public async Task&lt;RestApiResponse&lt;T>> Do&lt;T>(RequestSettings requestSettings, params string[] parts)\r\n            => await Request&lt;T>(requestSettings, parts);\r\n        public async Task&lt;RestApiResponse&lt;T>> Get&lt;T>(params string[] parts)\r\n            => await Request&lt;T>(new RequestSettings(HttpMethod.Get), parts);\r\n        public async Task&lt;RestApiResponse&lt;T>> Post&lt;T>(object content, params string[] parts)\r\n            => await Request&lt;T>(new RequestSettings(HttpMethod.Post, content), parts);\r\n        public async Task&lt;RestApiResponse&lt;T>> Put&lt;T>(object content, params string[] parts)\r\n            => await Request&lt;T>(new RequestSettings(HttpMethod.Put, content), parts);\r\n        public async Task&lt;RestApiResponse&lt;T>> Delete&lt;T>(params string[] parts)\r\n            => await Request&lt;T>(new RequestSettings(HttpMethod.Delete), parts);\r\n    }\r\n}\r\n<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[6,4,1],"tags":[],"class_list":["post-2681","post","type-post","status-publish","format-standard","hentry","category-dotnet","category-programming","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2681","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=2681"}],"version-history":[{"count":8,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2681\/revisions"}],"predecessor-version":[{"id":6994,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2681\/revisions\/6994"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=2681"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=2681"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=2681"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}