forked from loafle/openapi-generator-original
Merge pull request #223 from darkcube/master
CSharp: Multipart form submission
This commit is contained in:
commit
d9de57da6f
@ -45,6 +45,7 @@
|
|||||||
// query params
|
// query params
|
||||||
var queryParams = new Dictionary<String, String>();
|
var queryParams = new Dictionary<String, String>();
|
||||||
var headerParams = new Dictionary<String, String>();
|
var headerParams = new Dictionary<String, String>();
|
||||||
|
var formParams = new Dictionary<String, object>();
|
||||||
|
|
||||||
{{#requiredParamCount}}
|
{{#requiredParamCount}}
|
||||||
// verify required params are set
|
// verify required params are set
|
||||||
@ -53,9 +54,8 @@
|
|||||||
}
|
}
|
||||||
{{/requiredParamCount}}
|
{{/requiredParamCount}}
|
||||||
|
|
||||||
string paramStr = null;
|
|
||||||
{{#queryParams}}if ({{paramName}} != null){
|
{{#queryParams}}if ({{paramName}} != null){
|
||||||
paramStr = ({{paramName}} != null && {{paramName}} is DateTime) ? ((DateTime)(object){{paramName}}).ToString("u") : Convert.ToString({{paramName}});
|
string paramStr = ({{paramName}} is DateTime) ? ((DateTime)(object){{paramName}}).ToString("u") : Convert.ToString({{paramName}});
|
||||||
queryParams.Add("{{paramName}}", paramStr);
|
queryParams.Add("{{paramName}}", paramStr);
|
||||||
}
|
}
|
||||||
{{/queryParams}}
|
{{/queryParams}}
|
||||||
@ -63,17 +63,32 @@
|
|||||||
{{#headerParams}}headerParams.Add("{{paramName}}", {{paramName}});
|
{{#headerParams}}headerParams.Add("{{paramName}}", {{paramName}});
|
||||||
{{/headerParams}}
|
{{/headerParams}}
|
||||||
|
|
||||||
try {
|
{{#formParams}}if ({{paramName}} != null){
|
||||||
var response = apiInvoker.invokeAPI(basePath, path, "{{httpMethod}}", queryParams, {{#bodyParam}}{{bodyParam}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}, headerParams);
|
if({{paramName}} is byte[]) {
|
||||||
if(response != null){
|
formParams.Add("{{paramName}}", {{paramName}});
|
||||||
return {{#returnType}}({{{returnType}}}) ApiInvoker.deserialize(response, typeof({{{returnType}}})){{/returnType}};
|
} else {
|
||||||
|
string paramStr = ({{paramName}} is DateTime) ? ((DateTime)(object){{paramName}}).ToString("u") : Convert.ToString({{paramName}});
|
||||||
|
formParams.Add("{{paramName}}", paramStr);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
return {{#returnType}}null{{/returnType}};
|
{{/formParams}}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof({{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}) == typeof(byte[])) {
|
||||||
|
var response = apiInvoker.invokeBinaryAPI(basePath, path, "GET", queryParams, null, headerParams, formParams);
|
||||||
|
return {{#returnType}}((object)response) as {{{returnType}}}{{/returnType}};
|
||||||
|
} else {
|
||||||
|
var response = apiInvoker.invokeAPI(basePath, path, "{{httpMethod}}", queryParams, {{#bodyParam}}{{bodyParam}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}, headerParams, formParams);
|
||||||
|
if(response != null){
|
||||||
|
return {{#returnType}}({{{returnType}}}) ApiInvoker.deserialize(response, typeof({{{returnType}}})){{/returnType}};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {{#returnType}}null{{/returnType}};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (ApiException ex) {
|
} catch (ApiException ex) {
|
||||||
if(ex.ErrorCode == 404) {
|
if(ex.ErrorCode == 404) {
|
||||||
return {{#returnType}} null{{/returnType}};
|
return {{#returnType}}null{{/returnType}};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw ex;
|
throw ex;
|
||||||
|
@ -44,7 +44,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string invokeAPI(string host, string path, string method, Dictionary<String, String> queryParams, object body, Dictionary<String, String> headerParams) {
|
public string invokeAPI(string host, string path, string method, Dictionary<String, String> queryParams, object body, Dictionary<String, String> headerParams, Dictionary<String, object> formParams)
|
||||||
|
{
|
||||||
|
return invokeAPIInternal(host, path, method, false, queryParams, body, headerParams, formParams) as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] invokeBinaryAPI(string host, string path, string method, Dictionary<String, String> queryParams, object body, Dictionary<String, String> headerParams, Dictionary<String, object> 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<String, String> queryParams, object body, Dictionary<String, String> headerParams, Dictionary<String, object> formParams) {
|
||||||
var b = new StringBuilder();
|
var b = new StringBuilder();
|
||||||
|
|
||||||
foreach (var queryParamItem in queryParams)
|
foreach (var queryParamItem in queryParams)
|
||||||
@ -60,9 +70,21 @@
|
|||||||
host = host.EndsWith("/") ? host.Substring(0, host.Length - 1) : host;
|
host = host.EndsWith("/") ? host.Substring(0, host.Length - 1) : host;
|
||||||
|
|
||||||
var client = WebRequest.Create(host + path + querystring);
|
var client = WebRequest.Create(host + path + querystring);
|
||||||
client.ContentType = "application/json";
|
|
||||||
client.Method = method;
|
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)
|
foreach (var headerParamsItem in headerParams)
|
||||||
{
|
{
|
||||||
client.Headers.Add(headerParamsItem.Key, headerParamsItem.Value);
|
client.Headers.Add(headerParamsItem.Key, headerParamsItem.Value);
|
||||||
@ -79,9 +101,17 @@
|
|||||||
case "POST":
|
case "POST":
|
||||||
case "PUT":
|
case "PUT":
|
||||||
case "DELETE":
|
case "DELETE":
|
||||||
var swRequestWriter = new StreamWriter(client.GetRequestStream());
|
using (Stream requestStream = client.GetRequestStream())
|
||||||
swRequestWriter.Write(serialize(body));
|
{
|
||||||
swRequestWriter.Close();
|
if (formData != null)
|
||||||
|
{
|
||||||
|
requestStream.Write(formData, 0, formData.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
var swRequestWriter = new StreamWriter(requestStream);
|
||||||
|
swRequestWriter.Write(serialize(body));
|
||||||
|
swRequestWriter.Close();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ApiException(500, "unknown method type " + method);
|
throw new ApiException(500, "unknown method type " + method);
|
||||||
@ -96,10 +126,22 @@
|
|||||||
throw new ApiException((int)webResponse.StatusCode, webResponse.StatusDescription);
|
throw new ApiException((int)webResponse.StatusCode, webResponse.StatusDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
var responseReader = new StreamReader(webResponse.GetResponseStream());
|
if (binaryResponse)
|
||||||
var responseData = responseReader.ReadToEnd();
|
{
|
||||||
responseReader.Close();
|
using (var memoryStream = new MemoryStream())
|
||||||
return responseData;
|
{
|
||||||
|
webResponse.GetResponseStream().CopyTo(memoryStream);
|
||||||
|
return memoryStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using (var responseReader = new StreamReader(webResponse.GetResponseStream()))
|
||||||
|
{
|
||||||
|
var responseData = responseReader.ReadToEnd();
|
||||||
|
return responseData;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(WebException ex)
|
catch(WebException ex)
|
||||||
{
|
{
|
||||||
@ -113,5 +155,53 @@
|
|||||||
throw new ApiException(statusCode, ex.Message);
|
throw new ApiException(statusCode, ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static byte[] GetMultipartFormData(Dictionary<string, object> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class BasicCSharpGenerator extends BasicGenerator {
|
|||||||
* We are using csharp objects instead of primitives to avoid showing default
|
* We are using csharp objects instead of primitives to avoid showing default
|
||||||
* primitive values when the API returns missing data. For instance, having a
|
* primitive values when the API returns missing data. For instance, having a
|
||||||
* {"count":0} != count is unknown. You can change this to use primitives if you
|
* {"count":0} != count is unknown. You can change this to use primitives if you
|
||||||
* desire, but update the default values as well or they'll be set to null in
|
* desire, but update the default values as well or they'll be set to null in
|
||||||
* variable declarations.
|
* variable declarations.
|
||||||
*/
|
*/
|
||||||
override def typeMapping = Map(
|
override def typeMapping = Map(
|
||||||
@ -54,7 +54,9 @@ class BasicCSharpGenerator extends BasicGenerator {
|
|||||||
"double" -> "double?",
|
"double" -> "double?",
|
||||||
"object" -> "object",
|
"object" -> "object",
|
||||||
"Date" -> "DateTime?",
|
"Date" -> "DateTime?",
|
||||||
"date" -> "DateTime?")
|
"date" -> "DateTime?",
|
||||||
|
"File" -> "byte[]",
|
||||||
|
"file" -> "byte[]")
|
||||||
|
|
||||||
// location of templates
|
// location of templates
|
||||||
override def templateDir = "csharp"
|
override def templateDir = "csharp"
|
||||||
@ -70,11 +72,11 @@ class BasicCSharpGenerator extends BasicGenerator {
|
|||||||
// template used for models
|
// template used for models
|
||||||
apiTemplateFiles += "api.mustache" -> ".cs"
|
apiTemplateFiles += "api.mustache" -> ".cs"
|
||||||
|
|
||||||
override def reservedWords = Set("abstract", "continue", "for", "new", "switch", "assert",
|
override def reservedWords = Set("abstract", "continue", "for", "new", "switch", "assert",
|
||||||
"default", "if", "package", "synchronized", "do", "goto", "private", "this", "break",
|
"default", "if", "package", "synchronized", "do", "goto", "private", "this", "break",
|
||||||
"implements", "protected", "throw", "else", "import", "public", "throws", "case",
|
"implements", "protected", "throw", "else", "import", "public", "throws", "case",
|
||||||
"enum", "instanceof", "return", "transient", "catch", "extends", "try", "final",
|
"enum", "instanceof", "return", "transient", "catch", "extends", "try", "final",
|
||||||
"interface", "static", "void", "class", "finally", "strictfp", "volatile", "const",
|
"interface", "static", "void", "class", "finally", "strictfp", "volatile", "const",
|
||||||
"native", "super", "while")
|
"native", "super", "while")
|
||||||
|
|
||||||
// import/require statements for specific datatypes
|
// import/require statements for specific datatypes
|
||||||
@ -180,7 +182,7 @@ class BasicCSharpGenerator extends BasicGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override def escapeReservedWord(word: String) = {
|
override def escapeReservedWord(word: String) = {
|
||||||
if (reservedWords.contains(word))
|
if (reservedWords.contains(word))
|
||||||
throw new Exception("reserved word " + "\"" + word + "\" not allowed")
|
throw new Exception("reserved word " + "\"" + word + "\" not allowed")
|
||||||
else word
|
else word
|
||||||
}
|
}
|
||||||
@ -193,8 +195,8 @@ class BasicCSharpGenerator extends BasicGenerator {
|
|||||||
capitalize(name)
|
capitalize(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
def capitalize(s: String) = {
|
def capitalize(s: String) = {
|
||||||
s(0).toUpper + s.substring(1, s.length).toLowerCase
|
s(0).toUpper + s.substring(1, s.length).toLowerCase
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// supporting classes
|
// supporting classes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user