csharp.apiInvoker.mustache Maven / Gradle / Ivy
The newest version!
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Newtonsoft.Json;
namespace {{invokerPackage}} {
public class ApiInvoker {
private static readonly ApiInvoker _instance = new ApiInvoker();
private Dictionary defaultHeaderMap = new Dictionary();
public static ApiInvoker GetInstance() {
return _instance;
}
public void addDefaultHeader(string key, string value) {
defaultHeaderMap.Add(key, value);
}
public string escapeString(string str) {
return str;
}
public static object deserialize(string json, Type type) {
try
{
return JsonConvert.DeserializeObject(json, type);
}
catch (IOException e) {
throw new ApiException(500, e.Message);
}
}
public static string serialize(object obj) {
try
{
return obj != null ? JsonConvert.SerializeObject(obj) : null;
}
catch (Exception e) {
throw new ApiException(500, e.Message);
}
}
public string invokeAPI(string host, string path, string method, Dictionary queryParams, object body, Dictionary headerParams, Dictionary formParams)
{
return invokeAPIInternal(host, path, method, false, queryParams, body, headerParams, formParams) as string;
}
public byte[] invokeBinaryAPI(string host, string path, string method, Dictionary queryParams, object body, Dictionary headerParams, Dictionary formParams)
{
return invokeAPIInternal(host, path, method, true, queryParams, body, headerParams, formParams) as byte[];
}
private object invokeAPIInternal(string host, string path, string method, bool binaryResponse, Dictionary queryParams, object body, Dictionary headerParams, Dictionary formParams) {
var b = new StringBuilder();
foreach (var queryParamItem in queryParams)
{
var value = queryParamItem.Value;
if (value == null) continue;
b.Append(b.ToString().Length == 0 ? "?" : "&");
b.Append(escapeString(queryParamItem.Key)).Append("=").Append(escapeString(value));
}
var querystring = b.ToString();
host = host.EndsWith("/") ? host.Substring(0, host.Length - 1) : host;
var client = WebRequest.Create(host + path + querystring);
client.Method = method;
byte[] formData = null;
if (formParams.Count > 0)
{
string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
client.ContentType = "multipart/form-data; boundary=" + formDataBoundary;
formData = GetMultipartFormData(formParams, formDataBoundary);
client.ContentLength = formData.Length;
}
else
{
client.ContentType = "application/json";
}
foreach (var headerParamsItem in headerParams)
{
client.Headers.Add(headerParamsItem.Key, headerParamsItem.Value);
}
foreach (var defaultHeaderMapItem in defaultHeaderMap.Where(defaultHeaderMapItem => !headerParams.ContainsKey(defaultHeaderMapItem.Key)))
{
client.Headers.Add(defaultHeaderMapItem.Key, defaultHeaderMapItem.Value);
}
switch (method)
{
case "GET":
break;
case "POST":
case "PUT":
case "DELETE":
using (Stream requestStream = client.GetRequestStream())
{
if (formData != null)
{
requestStream.Write(formData, 0, formData.Length);
}
var swRequestWriter = new StreamWriter(requestStream);
swRequestWriter.Write(serialize(body));
swRequestWriter.Close();
}
break;
default:
throw new ApiException(500, "unknown method type " + method);
}
try
{
var webResponse = (HttpWebResponse)client.GetResponse();
if (webResponse.StatusCode != HttpStatusCode.OK)
{
webResponse.Close();
throw new ApiException((int)webResponse.StatusCode, webResponse.StatusDescription);
}
if (binaryResponse)
{
using (var memoryStream = new MemoryStream())
{
webResponse.GetResponseStream().CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
else
{
using (var responseReader = new StreamReader(webResponse.GetResponseStream()))
{
var responseData = responseReader.ReadToEnd();
return responseData;
}
}
}
catch(WebException ex)
{
var response = ex.Response as HttpWebResponse;
int statusCode = 0;
if (response != null)
{
statusCode = (int)response.StatusCode;
response.Close();
}
throw new ApiException(statusCode, ex.Message);
}
}
private static byte[] GetMultipartFormData(Dictionary postParameters, string boundary)
{
Stream formDataStream = new System.IO.MemoryStream();
bool needsCLRF = false;
foreach (var param in postParameters)
{
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
// Skip it on the first parameter, add it to subsequent parameters.
if (needsCLRF)
formDataStream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, Encoding.UTF8.GetByteCount("\r\n"));
needsCLRF = true;
if (param.Value is byte[])
{
string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n",
boundary,
param.Key,
"application/octet-stream");
formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, Encoding.UTF8.GetByteCount(postData));
// Write the file data directly to the Stream, rather than serializing it to a string.
formDataStream.Write((param.Value as byte[]), 0, (param.Value as byte[]).Length);
}
else
{
string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
boundary,
param.Key,
param.Value);
formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, Encoding.UTF8.GetByteCount(postData));
}
}
// Add the end of the request. Start with a newline
string footer = "\r\n--" + boundary + "--\r\n";
formDataStream.Write(Encoding.UTF8.GetBytes(footer), 0, Encoding.UTF8.GetByteCount(footer));
// Dump the Stream into a byte[]
formDataStream.Position = 0;
byte[] formData = new byte[formDataStream.Length];
formDataStream.Read(formData, 0, formData.Length);
formDataStream.Close();
return formData;
}
}
}