{{>partial_header}} using System; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using System.IO; using System.Web; using System.Linq; using System.Text; using Newtonsoft.Json; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; namespace {{packageName}}.Client { /// /// API client is mainly responsible for making the HTTP call to the API backend. /// public class ApiClient { public JsonSerializerSettings SerializerSettings = new JsonSerializerSettings { ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }; /// /// Allows for extending request processing for generated code. /// /// The RestSharp request object public virtual void InterceptRequest(HttpRequestMessage request) { } /// /// Allows for extending response processing for generated code. /// /// The RestSharp request object /// The RestSharp response object public virtual void InterceptResponse(HttpRequestMessage request, HttpResponseMessage response) { } /// /// Initializes a new instance of the class /// with default configuration. /// /// The base path. public ApiClient(HttpClient client) { RestClient = client; } /// /// Gets or sets the Configuration. /// /// An instance of the Configuration. public Configuration Configuration { get; set; } /// /// Gets or sets the RestClient. /// /// An instance of the RestClient public HttpClient RestClient { get; set; } private HttpMethod parseHttpMethod(string method) { if (method == "GET") return HttpMethod.Get; if (method == "POST") return HttpMethod.Post; if (method == "PUT") return HttpMethod.Put; if (method == "DELETE") return HttpMethod.Delete; if (method == "HEAD") return HttpMethod.Head; if (method == "OPTIONS") return HttpMethod.Options; throw new ArgumentException($"Cannot parse Http Method: {method}"); } // Creates and sets up a RestRequest prior to a call. private HttpRequestMessage PrepareRequest(String path, string method, Dictionary queryParams, string postBody, Dictionary headerParams, Dictionary formParams, String contentType) { string url = path; // add query parameter, if any if (queryParams.Any()) { var query = ToQueryString(queryParams); url += "?" + query; } var request = new HttpRequestMessage(parseHttpMethod(method), url); // add header parameter, if any foreach (var param in headerParams) request.Headers.Add(param.Key, param.Value); if (formParams.Any()) { request.Content = new FormUrlEncodedContent(formParams); } if (postBody != null) // http body (model or byte[]) parameter { request.Content = new StringContent(postBody, Encoding.UTF8, "application/json"); } return request; } public static string ToQueryString(Dictionary queryParams) { var ps = (from kv in queryParams select string.Format("{0}={1}", HttpUtility.UrlEncode(kv.Key), HttpUtility.UrlEncode(kv.Value))); return string.Join("&", ps); } /// /// Makes the HTTP request (Sync). /// /// URL path. /// HTTP method. /// Query parameters. /// Header parameters. /// Form parameters. /// File parameters. /// Content Type of the request /// Object public virtual HttpResponseMessage CallApi( String path, string method, Dictionary queryParams, string postBody, Dictionary headerParams, Dictionary formParams, String contentType) { var request = PrepareRequest(path, method, queryParams, postBody, headerParams, formParams, contentType); InterceptRequest(request); HttpResponseMessage response = RestClient.SendAsync(request).ConfigureAwait(false).GetAwaiter().GetResult(); InterceptResponse(request, response); return response; } /// /// Makes the asynchronous HTTP request. /// /// URL path. /// HTTP method. /// Query parameters. /// Header parameters. /// Form parameters. /// File parameters. /// Content type. /// The Task instance. public virtual async Task CallApiAsync( String path, string method, Dictionary queryParams, string postBody, Dictionary headerParams, Dictionary formParams, String contentType) { var request = PrepareRequest(path, method, queryParams, postBody, headerParams, formParams, contentType); InterceptRequest(request); HttpResponseMessage response = await RestClient.SendAsync(request).ConfigureAwait(false); InterceptResponse(request, response); return response; } /// /// Escape string (url-encoded). /// /// String to be escaped. /// Escaped string. public virtual string EscapeString(string str) { return UrlEncode(str); } /// /// If parameter is DateTime, output in a formatted string (default ISO 8601), customizable with Configuration.DateTime. /// If parameter is a list, join the list with ",". /// Otherwise just return the string. /// /// The parameter (header, path, query, form). /// Formatted string. public virtual string ParameterToString(object obj) { if (obj is DateTime) // Return a formatted date string - Can be customized with Configuration.DateTimeFormat // Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o") // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 // For example: 2009-06-15T13:45:30.0000000 return ((DateTime)obj).ToString(Configuration.DateTimeFormat); else if (obj is DateTimeOffset) // Return a formatted date string - Can be customized with Configuration.DateTimeFormat // Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o") // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 // For example: 2009-06-15T13:45:30.0000000 return ((DateTimeOffset)obj).ToString(Configuration.DateTimeFormat); else if (obj is IList) { var flattenedString = new StringBuilder(); foreach (var param in (IList)obj) { if (flattenedString.Length > 0) flattenedString.Append(","); flattenedString.Append(param); } return flattenedString.ToString(); } else return Convert.ToString(obj); } /// /// Deserialize the JSON string into a proper object. /// /// The HTTP response. /// Object type. /// Object representation of the JSON string. public virtual object Deserialize(string body, Type type) { // at this point, it must be a model (json) try { return JsonConvert.DeserializeObject(body, type, SerializerSettings); } catch (Exception e) { throw new ApiException(500, e.Message); } } /// /// Serialize an input (model) into JSON string /// /// Object. /// JSON string. public virtual String Serialize(object obj) { try { return obj != null ? JsonConvert.SerializeObject(obj) : null; } catch (Exception e) { throw new ApiException(500, e.Message); } } /// /// Select the Content-Type header's value from the given content-type array: /// if JSON exists in the given array, use it; /// otherwise use the first one defined in 'consumes' /// /// The Content-Type array to select from. /// The Content-Type header to use. public virtual String SelectHeaderContentType(String[] contentTypes) { if (contentTypes.Length == 0) return null; if (contentTypes.Contains("application/vnd.fht360.preserveCircularReference+json", StringComparer.OrdinalIgnoreCase)) return "application/vnd.fht360.preserveCircularReference+json"; return contentTypes[0]; // use the first content type specified in 'consumes' } /// /// Select the Accept header's value from the given accepts array: /// if JSON exists in the given array, use it; /// otherwise use all of them (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. public virtual String SelectHeaderAccept(String[] accepts) { if (accepts.Length == 0) return null; if (accepts.Contains("application/vnd.fht360.preserveCircularReference+json", StringComparer.OrdinalIgnoreCase)) return "application/vnd.fht360.preserveCircularReference+json"; return String.Join(",", accepts); } /// /// Encode string in base64 format. /// /// String to be encoded. /// Encoded string. public static string Base64Encode(string text) { return System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(text)); } /// /// Convert stream to byte array /// Credit/Ref: http://stackoverflow.com/a/221941/677735 /// /// Input stream to be converted /// Byte array public static byte[] ReadAsBytes(Stream input) { byte[] buffer = new byte[16 * 1024]; using (MemoryStream ms = new MemoryStream()) { int read; while ((read = input.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, read); } return ms.ToArray(); } } /// /// URL encode a string /// Credit/Ref: https://github.com/restsharp/RestSharp/blob/master/RestSharp/Extensions/StringExtensions.cs#L50 /// /// String to be URL encoded /// Byte array public static string UrlEncode(string input) { const int maxLength = 32766; if (input == null) { throw new ArgumentNullException("input"); } if (input.Length <= maxLength) { return Uri.EscapeDataString(input); } StringBuilder sb = new StringBuilder(input.Length * 2); int index = 0; while (index < input.Length) { int length = Math.Min(input.Length - index, maxLength); string subString = input.Substring(index, length); sb.Append(Uri.EscapeDataString(subString)); index += subString.Length; } return sb.ToString(); } /// /// Sanitize filename by removing the path /// /// Filename /// Filename public static string SanitizeFilename(string filename) { Match match = Regex.Match(filename, @".*[/\\](.*)$"); if (match.Success) { return match.Groups[1].Value; } else { return filename; } } } }