{{>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;
}
}
}
}