Skip to content

[C#] add binary support #1864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public CSharpClientCodegen() {

typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("binary", "byte[]");
typeMapping.put("boolean", "bool?");
typeMapping.put("integer", "int?");
typeMapping.put("float", "float?");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ namespace {{packageName}}.Client

// Creates and sets up a RestRequest prior to a call.
private RestRequest PrepareRequest(
String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
String path, RestSharp.Method method, Dictionary<String, String> queryParams, Object postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams)
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams,
String contentType)
{
var request = new RestRequest(path, method);

Expand All @@ -103,8 +104,17 @@ namespace {{packageName}}.Client
foreach(var param in fileParams)
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);

if (postBody != null) // http body (model) parameter
request.AddParameter("application/json", postBody, ParameterType.RequestBody);
if (postBody != null) // http body (model or byte[]) parameter
{
if (postBody.GetType() == typeof(String))
{
request.AddParameter("application/json", postBody, ParameterType.RequestBody);
}
else if (postBody.GetType() == typeof(byte[]))
{
request.AddParameter(contentType, postBody, ParameterType.RequestBody);
}
}

return request;
}
Expand All @@ -120,14 +130,18 @@ namespace {{packageName}}.Client
/// <param name="formParams">Form parameters.</param>
/// <param name="fileParams">File parameters.</param>
/// <param name="pathParams">Path parameters.</param>
/// <param name="contentType">Content Type of the request</param>
/// <returns>Object</returns>
public Object CallApi(
String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
String path, RestSharp.Method method, Dictionary<String, String> queryParams, Object postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams)
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams,
String contentType)
{
var request = PrepareRequest(
path, method, queryParams, postBody, headerParams, formParams, fileParams, pathParams);
path, method, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, contentType);

var response = RestClient.Execute(request);
return (Object) response;
}
Expand All @@ -143,14 +157,17 @@ namespace {{packageName}}.Client
/// <param name="formParams">Form parameters.</param>
/// <param name="fileParams">File parameters.</param>
/// <param name="pathParams">Path parameters.</param>
/// <param name="contentType">Content type.</param>
/// <returns>The Task instance.</returns>
public async System.Threading.Tasks.Task<Object> CallApiAsync(
String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
String path, RestSharp.Method method, Dictionary<String, String> queryParams, Object postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams)
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams,
String contentType)
{
var request = PrepareRequest(
path, method, queryParams, postBody, headerParams, formParams, fileParams, pathParams);
path, method, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, contentType);
var response = await RestClient.ExecuteTaskAsync(request);
return (Object)response;
}
Expand Down Expand Up @@ -230,6 +247,10 @@ namespace {{packageName}}.Client
{
return content;
}
else if (type == typeof(byte[])) // return byte array
{
return data;
}

if (type == typeof(Stream))
{
Expand Down Expand Up @@ -276,11 +297,11 @@ namespace {{packageName}}.Client
}

/// <summary>
/// Serialize an object into JSON string.
/// Serialize an input (model) into JSON string
/// </summary>
/// <param name="obj">Object.</param>
/// <returns>JSON string.</returns>
public string Serialize(object obj)
public String Serialize(object obj)
{
try
{
Expand All @@ -292,6 +313,24 @@ namespace {{packageName}}.Client
}
}

/// <summary>
/// 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'
/// </summary>
/// <param name="contentTypes">The Content-Type array to select from.</param>
/// <returns>The Content-Type header to use.</returns>
public String SelectHeaderContentType(String[] contentTypes)
{
if (contentTypes.Length == 0)
return null;

if (contentTypes.Contains("application/json", StringComparer.OrdinalIgnoreCase))
return "application/json";

return contentTypes[0]; // use the first content type specified in 'consumes'
}

/// <summary>
/// Select the Accept header's value from the given accepts array:
/// if JSON exists in the given array, use it;
Expand Down
56 changes: 39 additions & 17 deletions modules/swagger-codegen/src/main/resources/csharp/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ namespace {{packageName}}.Api
{
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{operationId}}");
if ({{paramName}} == null)
throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
{{/required}}{{/allParams}}

var path_ = "{{path}}";
Expand All @@ -164,15 +165,21 @@ namespace {{packageName}}.Api
var headerParams = new Dictionary<String, String>(Configuration.DefaultHeader);
var formParams = new Dictionary<String, String>();
var fileParams = new Dictionary<String, FileParameter>();
String postBody = null;
Object postBody = null;

// to determine the Content-Type header
String[] httpContentTypes = new String[] {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
String httpContentType = Configuration.ApiClient.SelectHeaderContentType(httpContentTypes);

// to determine the Accept header
String[] http_header_accepts = new String[] {
String[] httpHeaderAccepts = new String[] {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
String http_header_accept = Configuration.ApiClient.SelectHeaderAccept(http_header_accepts);
if (http_header_accept != null)
headerParams.Add("Accept", Configuration.ApiClient.SelectHeaderAccept(http_header_accepts));
String httpHeaderAccept = Configuration.ApiClient.SelectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAccept != null)
headerParams.Add("Accept", httpHeaderAccept);

// set "format" to json by default
// e.g. /pet/{petId}.{format} becomes /pet/{petId}.json
Expand All @@ -185,11 +192,16 @@ namespace {{packageName}}.Api
{{/headerParams}}
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", Configuration.ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", Configuration.ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
{{/formParams}}
{{#bodyParam}}postBody = Configuration.ApiClient.Serialize({{paramName}}); // http body (model) parameter
{{/bodyParam}}
{{#bodyParam}}if ({{paramName}}.GetType() != typeof(byte[]))
{
postBody = Configuration.ApiClient.Serialize({{paramName}}); // http body (model) parameter
}
else
{
postBody = {{paramName}}; // byte array
}{{/bodyParam}}

{{#authMethods}}
// authentication ({{name}}) required
{{#authMethods}}// authentication ({{name}}) required
{{#isApiKey}}{{#isKeyInHeader}}
var apiKeyValue = Configuration.GetApiKeyWithPrefix("{{keyParamName}}");
if (!String.IsNullOrEmpty(apiKeyValue))
Expand All @@ -214,7 +226,9 @@ namespace {{packageName}}.Api
{{/authMethods}}

// make the HTTP request
IRestResponse response = (IRestResponse) Configuration.ApiClient.CallApi(path_, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams);
IRestResponse response = (IRestResponse) Configuration.ApiClient.CallApi(path_,
Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, httpContentType);

int statusCode = (int) response.StatusCode;

Expand Down Expand Up @@ -261,15 +275,21 @@ namespace {{packageName}}.Api
var headerParams = new Dictionary<String, String>();
var formParams = new Dictionary<String, String>();
var fileParams = new Dictionary<String, FileParameter>();
String postBody = null;
Object postBody = null;

// to determine the Content-Type header
String[] httpContentTypes = new String[] {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
String httpContentType = Configuration.ApiClient.SelectHeaderContentType(httpContentTypes);

// to determine the Accept header
String[] http_header_accepts = new String[] {
String[] httpHeaderAccepts = new String[] {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
String http_header_accept = Configuration.ApiClient.SelectHeaderAccept(http_header_accepts);
if (http_header_accept != null)
headerParams.Add("Accept", Configuration.ApiClient.SelectHeaderAccept(http_header_accepts));
String httpHeaderAccept = Configuration.ApiClient.SelectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAccept != null)
headerParams.Add("Accept", httpHeaderAccept);

// set "format" to json by default
// e.g. /pet/{petId}.{format} becomes /pet/{petId}.json
Expand Down Expand Up @@ -311,7 +331,9 @@ namespace {{packageName}}.Api
{{/authMethods}}

// make the HTTP request
IRestResponse response = (IRestResponse) await Configuration.ApiClient.CallApiAsync(path_, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams);
IRestResponse response = (IRestResponse) await Configuration.ApiClient.CallApiAsync(path_,
Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, httpContentType);

int statusCode = (int) response.StatusCode;

Expand Down
93 changes: 93 additions & 0 deletions modules/swagger-codegen/src/test/resources/2_0/petstore.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,49 @@
"http"
],
"paths": {
"/pet?testing_byte_array=true": {
"post": {
"tags": [
"pet"
],
"summary": "Fake endpoint to test byte array in body parameter for adding a new pet to the store",
"description": "",
"operationId": "addPetUsingByteArray",
"consumes": [
"application/json",
"application/xml"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Pet object in the form of byte array",
"required": false,
"schema": {
"type": "string",
"format": "binary"
}
}
],
"responses": {
"405": {
"description": "Invalid input"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/pet": {
"post": {
"tags": [
Expand Down Expand Up @@ -206,6 +249,56 @@
]
}
},
"/pet/{petId}?testing_byte_array=true": {
"get": {
"tags": [
"pet"
],
"summary": "Fake endpoint to test byte array return by 'Find pet by ID'",
"description": "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions",
"operationId": "getPetByIdWithByteArray",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "petId",
"in": "path",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"404": {
"description": "Pet not found"
},
"200": {
"description": "successful operation",
"schema": {
"type": "string",
"format": "binary"
}
},
"400": {
"description": "Invalid ID supplied"
}
},
"security": [
{
"api_key": []
},
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/pet/{petId}": {
"get": {
"tags": [
Expand Down
Loading