diff --git a/.gitignore b/.gitignore
index ca54f525660..b17bf46aa10 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,4 @@ target
.idea
.lib
atlassian-ide-plugin.xml
+.DS_Store
diff --git a/bin/csharp-petstore.sh b/bin/csharp-petstore.sh
new file mode 100755
index 00000000000..3941d90896f
--- /dev/null
+++ b/bin/csharp-petstore.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+export CLASSPATH="$DIR/../target/lib/*:$DIR/../target/*"
+export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
+JAVA_OPTS=$JAVA_OPTS scala -cp $CLASSPATH "$@" samples/client/petstore/csharp/CsharpPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs.json special-key
\ No newline at end of file
diff --git a/build.sbt b/build.sbt
index 635c4675b20..00c094bf131 100644
--- a/build.sbt
+++ b/build.sbt
@@ -96,6 +96,11 @@ pomExtra <<= (pomExtra, name, description) {(pom, name, desc) => pom ++ Group(
Ivan Porto Carrero
http://flanders.co.nz/
+
+ radius314
+ Danny Gershman
+ danny.gershman@gmail.com
+
)}
diff --git a/samples/client/petstore/csharp/CSharpPetstoreCodegen.scala b/samples/client/petstore/csharp/CSharpPetstoreCodegen.scala
new file mode 100644
index 00000000000..4f876fa0751
--- /dev/null
+++ b/samples/client/petstore/csharp/CSharpPetstoreCodegen.scala
@@ -0,0 +1,45 @@
+/**
+ * Copyright 2012 Wordnik, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.wordnik.swagger.codegen.BasicCSharpGenerator
+
+object CSharpPetstoreCodegen extends BasicCSharpGenerator {
+ def main(args: Array[String]) = generateClient(args)
+
+ // location of templates
+ override def templateDir = "csharp"
+
+ // where to write generated code
+ override def destinationDir = "samples/client/petstore/csharp/src"
+
+ // package for api invoker, error files
+ override def invokerPackage = Some("Com.Wordnik.Petstore")
+
+ // package for models
+ override def modelPackage = Some("Com.Wordnik.Petstore.Model")
+
+ // package for api classes
+ override def apiPackage = Some("Com.Wordnik.Petstore.Api")
+
+ // supporting classes
+ override def supportingFiles =
+ List(
+ ("apiInvoker.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiInvoker.cs"),
+ ("apiException.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiException.cs"),
+ ("Newtonsoft.Json.dll", "samples/client/petstore/csharp/bin", "Newtonsoft.Json.dll"),
+ ("compile.mustache", "samples/client/petstore/csharp", "compile.bat"))
+}
+
diff --git a/samples/client/petstore/csharp/bin/Com.Wordnik.Petstore.dll b/samples/client/petstore/csharp/bin/Com.Wordnik.Petstore.dll
new file mode 100644
index 00000000000..f4656a1bf40
Binary files /dev/null and b/samples/client/petstore/csharp/bin/Com.Wordnik.Petstore.dll differ
diff --git a/samples/client/petstore/csharp/bin/Newtonsoft.Json.dll b/samples/client/petstore/csharp/bin/Newtonsoft.Json.dll
new file mode 100644
index 00000000000..26fdaffec14
Binary files /dev/null and b/samples/client/petstore/csharp/bin/Newtonsoft.Json.dll differ
diff --git a/samples/client/petstore/csharp/compile.bat b/samples/client/petstore/csharp/compile.bat
new file mode 100644
index 00000000000..13a6e91643e
--- /dev/null
+++ b/samples/client/petstore/csharp/compile.bat
@@ -0,0 +1,2 @@
+SET CSCPATH=C:\windows\microsoft.net\Framework\v4.0.30319
+%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll /target:library /out:bin/Com.Wordnik.Petstore.dll /recurse:src\*.cs
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/PetApi.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/PetApi.cs
new file mode 100644
index 00000000000..ede61e78a28
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/PetApi.cs
@@ -0,0 +1,172 @@
+ using System;
+ using System.Collections.Generic;
+ using Com.Wordnik.Petstore;
+ using Com.Wordnik.Petstore.Model;
+ namespace Com.Wordnik.Petstore.Api {
+ public class PetApi {
+ string basePath = "http://petstore.swagger.wordnik.com/api";
+ private readonly ApiInvoker apiInvoker = ApiInvoker.GetInstance();
+
+ public ApiInvoker getInvoker() {
+ return apiInvoker;
+ }
+
+ public void setBasePath(string basePath) {
+ this.basePath = basePath;
+ }
+
+ public String getBasePath() {
+ return basePath;
+ }
+
+ public Pet getPetById (string Petid) {
+ // create path and map variables
+ var path = "/pet.{format}/{petId}".Replace("{format}","json").Replace("{" + "Petid" + "}", apiInvoker.escapeString(Petid.ToString()));
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Petid == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams);
+ if(response != null){
+ return (Pet) ApiInvoker.deserialize(response, typeof(Pet));
+ }
+ else {
+ return null;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return null;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void addPet (Pet body) {
+ // create path and map variables
+ var path = "/pet.{format}".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (body == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void updatePet (Pet body) {
+ // create path and map variables
+ var path = "/pet.{format}".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (body == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "PUT", queryParams, body, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public List findPetsByStatus (string Status) {
+ // create path and map variables
+ var path = "/pet.{format}/findByStatus".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Status == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ if (Status != null)
+ queryParams.Add("Status", Status);
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams);
+ if(response != null){
+ return (List) ApiInvoker.deserialize(response, typeof(List));
+ }
+ else {
+ return null;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return null;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public List findPetsByTags (string Tags) {
+ // create path and map variables
+ var path = "/pet.{format}/findByTags".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Tags == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ if (Tags != null)
+ queryParams.Add("Tags", Tags);
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams);
+ if(response != null){
+ return (List) ApiInvoker.deserialize(response, typeof(List));
+ }
+ else {
+ return null;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return null;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ }
+ }
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/StoreApi.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/StoreApi.cs
new file mode 100644
index 00000000000..90ed1f5d6c1
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/StoreApi.cs
@@ -0,0 +1,110 @@
+ using System;
+ using System.Collections.Generic;
+ using Com.Wordnik.Petstore;
+ using Com.Wordnik.Petstore.Model;
+ namespace Com.Wordnik.Petstore.Api {
+ public class StoreApi {
+ string basePath = "http://petstore.swagger.wordnik.com/api";
+ private readonly ApiInvoker apiInvoker = ApiInvoker.GetInstance();
+
+ public ApiInvoker getInvoker() {
+ return apiInvoker;
+ }
+
+ public void setBasePath(string basePath) {
+ this.basePath = basePath;
+ }
+
+ public String getBasePath() {
+ return basePath;
+ }
+
+ public Order getOrderById (string Orderid) {
+ // create path and map variables
+ var path = "/store.{format}/order/{orderId}".Replace("{format}","json").Replace("{" + "Orderid" + "}", apiInvoker.escapeString(Orderid.ToString()));
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Orderid == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams);
+ if(response != null){
+ return (Order) ApiInvoker.deserialize(response, typeof(Order));
+ }
+ else {
+ return null;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return null;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void deleteOrder (string Orderid) {
+ // create path and map variables
+ var path = "/store.{format}/order/{orderId}".Replace("{format}","json").Replace("{" + "Orderid" + "}", apiInvoker.escapeString(Orderid.ToString()));
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Orderid == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "DELETE", queryParams, null, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void placeOrder (Order body) {
+ // create path and map variables
+ var path = "/store.{format}/order".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (body == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ }
+ }
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/UserApi.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/UserApi.cs
new file mode 100644
index 00000000000..74b92228edd
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/UserApi.cs
@@ -0,0 +1,255 @@
+ using System;
+ using System.Collections.Generic;
+ using Com.Wordnik.Petstore;
+ using Com.Wordnik.Petstore.Model;
+ namespace Com.Wordnik.Petstore.Api {
+ public class UserApi {
+ string basePath = "http://petstore.swagger.wordnik.com/api";
+ private readonly ApiInvoker apiInvoker = ApiInvoker.GetInstance();
+
+ public ApiInvoker getInvoker() {
+ return apiInvoker;
+ }
+
+ public void setBasePath(string basePath) {
+ this.basePath = basePath;
+ }
+
+ public String getBasePath() {
+ return basePath;
+ }
+
+ public void createUsersWithArrayInput (List body) {
+ // create path and map variables
+ var path = "/user.{format}/createWithArray".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (body == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void createUser (User body) {
+ // create path and map variables
+ var path = "/user.{format}".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (body == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void createUsersWithListInput (List body) {
+ // create path and map variables
+ var path = "/user.{format}/createWithList".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (body == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void updateUser (string Username, User body) {
+ // create path and map variables
+ var path = "/user.{format}/{username}".Replace("{format}","json").Replace("{" + "Username" + "}", apiInvoker.escapeString(Username.ToString()));
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Username == null || body == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "PUT", queryParams, body, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void deleteUser (string Username) {
+ // create path and map variables
+ var path = "/user.{format}/{username}".Replace("{format}","json").Replace("{" + "Username" + "}", apiInvoker.escapeString(Username.ToString()));
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Username == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "DELETE", queryParams, null, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public User getUserByName (string Username) {
+ // create path and map variables
+ var path = "/user.{format}/{username}".Replace("{format}","json").Replace("{" + "Username" + "}", apiInvoker.escapeString(Username.ToString()));
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Username == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams);
+ if(response != null){
+ return (User) ApiInvoker.deserialize(response, typeof(User));
+ }
+ else {
+ return null;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return null;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public string loginUser (string Username, string Password) {
+ // create path and map variables
+ var path = "/user.{format}/login".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ // verify required params are set
+ if (Username == null || Password == null ) {
+ throw new ApiException(400, "missing required params");
+ }
+ if (Username != null)
+ queryParams.Add("Username", Username);
+ if (Password != null)
+ queryParams.Add("Password", Password);
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams);
+ if(response != null){
+ return (string) ApiInvoker.deserialize(response, typeof(string));
+ }
+ else {
+ return null;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return null;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ public void logoutUser () {
+ // create path and map variables
+ var path = "/user.{format}/logout".Replace("{format}","json");
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams);
+ if(response != null){
+ return ;
+ }
+ else {
+ return ;
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return ;
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ }
+ }
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiException.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiException.cs
new file mode 100644
index 00000000000..0da40246867
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiException.cs
@@ -0,0 +1,21 @@
+using System;
+
+namespace Com.Wordnik.Petstore {
+ public class ApiException : Exception {
+
+ private int errorCode = 0;
+
+ public ApiException() {}
+
+ public int ErrorCode {
+ get
+ {
+ return errorCode;
+ }
+ }
+
+ public ApiException(int errorCode, string message) : base(message) {
+ this.errorCode = errorCode;
+ }
+ }
+}
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiInvoker.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiInvoker.cs
new file mode 100644
index 00000000000..1388f77762b
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiInvoker.cs
@@ -0,0 +1,99 @@
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Net;
+ using System.Text;
+ using Newtonsoft.Json;
+
+ namespace Com.Wordnik.Petstore {
+ 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) {
+ 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.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":
+ var swRequestWriter = new StreamWriter(client.GetRequestStream());
+ swRequestWriter.Write(serialize(body));
+ swRequestWriter.Close();
+ break;
+ default:
+ throw new ApiException(500, "unknown method type " + method);
+ }
+ var webResponse = (HttpWebResponse) client.GetResponse();
+ if (webResponse.StatusCode != HttpStatusCode.OK) throw new ApiException((int) webResponse.StatusCode, webResponse.StatusDescription);
+
+ var responseReader = new StreamReader(webResponse.GetResponseStream());
+ var responseData = responseReader.ReadToEnd();
+ responseReader.Close();
+ return responseData;
+ }
+
+ }
+ }
+
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Category.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Category.cs
new file mode 100644
index 00000000000..48285458f91
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Category.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Com.Wordnik.Petstore.Model {
+ public class Category {
+ public long Id { get; set; }
+
+ public string Name { get; set; }
+
+ public override string ToString() {
+ var sb = new StringBuilder();
+ sb.Append("class Category {\n");
+ sb.Append(" Id: ").Append(Id).Append("\n");
+ sb.Append(" Name: ").Append(Name).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+ }
+ }
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Order.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Order.cs
new file mode 100644
index 00000000000..a3bf7af3a88
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Order.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Com.Wordnik.Petstore.Model {
+ public class Order {
+ public long Id { get; set; }
+
+ public long Petid { get; set; }
+
+ /* Order Status */
+ public string Status { get; set; }
+
+ public int Quantity { get; set; }
+
+ public DateTime Shipdate { get; set; }
+
+ public override string ToString() {
+ var sb = new StringBuilder();
+ sb.Append("class Order {\n");
+ sb.Append(" Id: ").Append(Id).Append("\n");
+ sb.Append(" Petid: ").Append(Petid).Append("\n");
+ sb.Append(" Status: ").Append(Status).Append("\n");
+ sb.Append(" Quantity: ").Append(Quantity).Append("\n");
+ sb.Append(" Shipdate: ").Append(Shipdate).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+ }
+ }
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Pet.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Pet.cs
new file mode 100644
index 00000000000..7fe96a64ddc
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Pet.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Com.Wordnik.Petstore.Model {
+ public class Pet {
+ public List Tags { get; set; }
+
+ public long Id { get; set; }
+
+ public Category Category { get; set; }
+
+ /* pet status in the store */
+ public string Status { get; set; }
+
+ public string Name { get; set; }
+
+ public List Photourls { get; set; }
+
+ public override string ToString() {
+ var sb = new StringBuilder();
+ sb.Append("class Pet {\n");
+ sb.Append(" Tags: ").Append(Tags).Append("\n");
+ sb.Append(" Id: ").Append(Id).Append("\n");
+ sb.Append(" Category: ").Append(Category).Append("\n");
+ sb.Append(" Status: ").Append(Status).Append("\n");
+ sb.Append(" Name: ").Append(Name).Append("\n");
+ sb.Append(" Photourls: ").Append(Photourls).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+ }
+ }
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Tag.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Tag.cs
new file mode 100644
index 00000000000..c73dc74c47a
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Tag.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Com.Wordnik.Petstore.Model {
+ public class Tag {
+ public long Id { get; set; }
+
+ public string Name { get; set; }
+
+ public override string ToString() {
+ var sb = new StringBuilder();
+ sb.Append("class Tag {\n");
+ sb.Append(" Id: ").Append(Id).Append("\n");
+ sb.Append(" Name: ").Append(Name).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+ }
+ }
diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/User.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/User.cs
new file mode 100644
index 00000000000..f3032e9a7bb
--- /dev/null
+++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/User.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Com.Wordnik.Petstore.Model {
+ public class User {
+ public long Id { get; set; }
+
+ public string Lastname { get; set; }
+
+ public string Phone { get; set; }
+
+ public string Username { get; set; }
+
+ public string Email { get; set; }
+
+ /* User Status */
+ public int Userstatus { get; set; }
+
+ public string Firstname { get; set; }
+
+ public string Password { get; set; }
+
+ public override string ToString() {
+ var sb = new StringBuilder();
+ sb.Append("class User {\n");
+ sb.Append(" Id: ").Append(Id).Append("\n");
+ sb.Append(" Lastname: ").Append(Lastname).Append("\n");
+ sb.Append(" Phone: ").Append(Phone).Append("\n");
+ sb.Append(" Username: ").Append(Username).Append("\n");
+ sb.Append(" Email: ").Append(Email).Append("\n");
+ sb.Append(" Userstatus: ").Append(Userstatus).Append("\n");
+ sb.Append(" Firstname: ").Append(Firstname).Append("\n");
+ sb.Append(" Password: ").Append(Password).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+ }
+ }
diff --git a/src/main/resources/csharp/Newtonsoft.Json.dll b/src/main/resources/csharp/Newtonsoft.Json.dll
new file mode 100644
index 00000000000..26fdaffec14
Binary files /dev/null and b/src/main/resources/csharp/Newtonsoft.Json.dll differ
diff --git a/src/main/resources/csharp/api.mustache b/src/main/resources/csharp/api.mustache
new file mode 100644
index 00000000000..b08081d81e9
--- /dev/null
+++ b/src/main/resources/csharp/api.mustache
@@ -0,0 +1,69 @@
+ using System;
+ using System.Collections.Generic;
+ using {{invokerPackage}};
+ using {{invokerPackage}}.Model;
+ {{#imports}}
+ {{/imports}}
+
+ namespace {{package}} {
+ {{#operations}}
+ public class {{classname}} {
+ string basePath = "{{basePath}}";
+ private readonly ApiInvoker apiInvoker = ApiInvoker.GetInstance();
+
+ public ApiInvoker getInvoker() {
+ return apiInvoker;
+ }
+
+ public void setBasePath(string basePath) {
+ this.basePath = basePath;
+ }
+
+ public String getBasePath() {
+ return basePath;
+ }
+
+ {{#operation}}
+ public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
+ // create path and map variables
+ var path = "{{path}}".Replace("{format}","json"){{#pathParams}}.Replace("{" + "{{paramName}}" + "}", apiInvoker.escapeString({{{paramName}}}.ToString())){{/pathParams}};
+
+ // query params
+ var queryParams = new Dictionary();
+ var headerParams = new Dictionary();
+
+ {{#requiredParamCount}}
+ // verify required params are set
+ if ({{/requiredParamCount}}{{#requiredParams}} {{paramName}} == null {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) {
+ throw new ApiException(400, "missing required params");
+ }
+ {{/requiredParamCount}}
+
+ {{#queryParams}}if ({{paramName}} != null)
+ queryParams.Add("{{paramName}}", {{paramName}});
+ {{/queryParams}}
+
+ {{#headerParams}}headerParams.Add("{{paramName}}", {{paramName}});
+ {{/headerParams}}
+
+ try {
+ var response = apiInvoker.invokeAPI(basePath, path, "{{httpMethod}}", queryParams, {{#bodyParam}}{{bodyParam}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}, headerParams);
+ if(response != null){
+ return {{#returnType}}({{{returnType}}}) ApiInvoker.deserialize(response, typeof({{{returnType}}})){{/returnType}};
+ }
+ else {
+ return {{#returnType}}null{{/returnType}};
+ }
+ } catch (ApiException ex) {
+ if(ex.ErrorCode == 404) {
+ return {{#returnType}} null{{/returnType}};
+ }
+ else {
+ throw ex;
+ }
+ }
+ }
+ {{/operation}}
+ }
+ {{/operations}}
+ }
\ No newline at end of file
diff --git a/src/main/resources/csharp/apiException.mustache b/src/main/resources/csharp/apiException.mustache
new file mode 100644
index 00000000000..3b371aea9a8
--- /dev/null
+++ b/src/main/resources/csharp/apiException.mustache
@@ -0,0 +1,21 @@
+using System;
+
+namespace {{invokerPackage}} {
+ public class ApiException : Exception {
+
+ private int errorCode = 0;
+
+ public ApiException() {}
+
+ public int ErrorCode {
+ get
+ {
+ return errorCode;
+ }
+ }
+
+ public ApiException(int errorCode, string message) : base(message) {
+ this.errorCode = errorCode;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/csharp/apiInvoker.mustache b/src/main/resources/csharp/apiInvoker.mustache
new file mode 100644
index 00000000000..c522d1545f6
--- /dev/null
+++ b/src/main/resources/csharp/apiInvoker.mustache
@@ -0,0 +1,98 @@
+ 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) {
+ 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.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":
+ var swRequestWriter = new StreamWriter(client.GetRequestStream());
+ swRequestWriter.Write(serialize(body));
+ swRequestWriter.Close();
+ break;
+ default:
+ throw new ApiException(500, "unknown method type " + method);
+ }
+ var webResponse = (HttpWebResponse) client.GetResponse();
+ if (webResponse.StatusCode != HttpStatusCode.OK) throw new ApiException((int) webResponse.StatusCode, webResponse.StatusDescription);
+
+ var responseReader = new StreamReader(webResponse.GetResponseStream());
+ var responseData = responseReader.ReadToEnd();
+ responseReader.Close();
+ return responseData;
+ }
+
+ }
+ }
diff --git a/src/main/resources/csharp/compile.mustache b/src/main/resources/csharp/compile.mustache
new file mode 100644
index 00000000000..b19235fde3c
--- /dev/null
+++ b/src/main/resources/csharp/compile.mustache
@@ -0,0 +1,2 @@
+SET CSCPATH=C:\windows\microsoft.net\Framework\v4.0.30319
+%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll /target:library /out:bin/{{invokerPackage}}.dll /recurse:src\*.cs
\ No newline at end of file
diff --git a/src/main/resources/csharp/model.mustache b/src/main/resources/csharp/model.mustache
new file mode 100644
index 00000000000..d9ef4ffbedd
--- /dev/null
+++ b/src/main/resources/csharp/model.mustache
@@ -0,0 +1,30 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+
+{{#models}}
+{{#model}}
+namespace {{package}} {
+ public class {{classname}} {
+ {{#vars}}
+
+ {{#description}}/* {{{description}}} */
+ {{/description}}
+ public {{{datatype}}} {{name}} { get; set; }
+
+ {{/vars}}
+
+ public override string ToString() {
+ var sb = new StringBuilder();
+ sb.Append("class {{classname}} {\n");
+ {{#vars}}
+ sb.Append(" {{name}}: ").Append({{name}}).Append("\n");
+ {{/vars}}
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+ }
+ {{/model}}
+ {{/models}}
+}
\ No newline at end of file
diff --git a/src/main/scala/com/wordnik/swagger/codegen/BasicCSharpGenerator.scala b/src/main/scala/com/wordnik/swagger/codegen/BasicCSharpGenerator.scala
new file mode 100644
index 00000000000..b7f2d1aab59
--- /dev/null
+++ b/src/main/scala/com/wordnik/swagger/codegen/BasicCSharpGenerator.scala
@@ -0,0 +1,189 @@
+/**
+ * Copyright 2012 Wordnik, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.wordnik.swagger.codegen
+
+import com.wordnik.swagger.model._
+
+object BasicCSharpGenerator extends BasicCSharpGenerator {
+ def main(args: Array[String]) = generateClient(args)
+}
+
+class BasicCSharpGenerator extends BasicGenerator {
+ override def defaultIncludes = Set(
+ "double",
+ "int",
+ "long",
+ "float",
+ "String",
+ "boolean",
+ "Boolean",
+ "Double",
+ "Integer",
+ "Long",
+ "Float")
+
+ /**
+ * We are using csharp objects instead of primitives to avoid showing default
+ * 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
+ * desire, but update the default values as well or they'll be set to null in
+ * variable declarations.
+ */
+ override def typeMapping = Map(
+ "boolean" -> "bool",
+ "string" -> "string",
+ "int" -> "int",
+ "float" -> "float",
+ "long" -> "long",
+ "double" -> "double",
+ "object" -> "object",
+ "Date" -> "DateTime",
+ "date" -> "DateTime")
+
+ // location of templates
+ override def templateDir = "csharp"
+
+ // where to write generated code
+ override def destinationDir = "generated-code/csharp/src/main/csharp"
+
+ // template used for models
+ modelTemplateFiles += "model.mustache" -> ".cs"
+
+ // template used for models
+ apiTemplateFiles += "api.mustache" -> ".cs"
+
+ override def reservedWords = Set("abstract", "continue", "for", "new", "switch", "assert",
+ "default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
+ "this", "break", "double", "implements", "protected", "throw", "byte", "else",
+ "import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
+ "catch", "extends", "short", "try", "char", "final", "interface", "static",
+ "void", "class", "finally", "strictfp", "volatile", "const", "float",
+ "native", "super", "while")
+
+ // import/require statements for specific datatypes
+ override def importMapping = Map()
+
+ // package for models
+ override def modelPackage = Some("Com.Wordnik.Client.Model")
+
+ // package for api classes
+ override def apiPackage = Some("Com.Wordnik.Client.Api")
+
+ // file suffix
+ override def fileSuffix = ".cs"
+
+ // response classes
+ override def processResponseClass(responseClass: String): Option[String] = {
+ responseClass match {
+ case "void" => None
+ case e: String => Some(typeMapping.getOrElse(e, e.replaceAll("\\[", "<").replaceAll("\\]", ">")))
+ }
+ }
+
+ override def processResponseDeclaration(responseClass: String): Option[String] = {
+ responseClass match {
+ case "void" => None
+ case e: String => Some(typeMapping.getOrElse(e, e.replaceAll("\\[", "<").replaceAll("\\]", ">")))
+ }
+ }
+
+ override def toDeclaredType(dt: String): String = {
+ val declaredType = dt.indexOf("[") match {
+ case -1 => dt
+ case n: Int => {
+ if (dt.substring(0, n) == "Array")
+ "List" + dt.substring(n).replaceAll("\\[", "<").replaceAll("\\]", ">")
+ else dt.replaceAll("\\[", "<").replaceAll("\\]", ">")
+ }
+ }
+ typeMapping.getOrElse(declaredType, declaredType)
+ }
+
+ override def toDeclaration(obj: ModelProperty) = {
+ var declaredType = toDeclaredType(obj.`type`)
+
+ declaredType match {
+ case "Array" => declaredType = "List"
+ case e: String => e
+ }
+
+ val defaultValue = toDefaultValue(declaredType, obj)
+ declaredType match {
+ case "List" => {
+ val inner = {
+ obj.items match {
+ case Some(items) => items.ref.getOrElse(items.`type`)
+ case _ => throw new Exception("no inner type defined")
+ }
+ }
+ declaredType += "<" + toDeclaredType(inner) + ">"
+ }
+ case _ =>
+ }
+ (declaredType, defaultValue)
+ }
+
+ /**
+ * we are defaulting to null values since the codegen uses csharp objects instead of primitives
+ * If you change to primitives, you can put in the appropriate values (0.0f, etc).
+ */
+ override def toDefaultValue(dataType: String, obj: ModelProperty) = {
+ dataType match {
+ case "Boolean" => "null"
+ case "Integer" => "null"
+ case "Long" => "null"
+ case "Float" => "null"
+ case "Double" => "null"
+ case "List" => {
+ val inner = {
+ obj.items match {
+ case Some(items) => items.ref.getOrElse(items.`type`)
+ case _ => throw new Exception("no inner type defined")
+ }
+ }
+ "new ArrayList<" + toDeclaredType(inner) + ">" + "()"
+ }
+ case _ => "null"
+ }
+ }
+
+ override def escapeReservedWord(word: String) = {
+ if (reservedWords.contains(word))
+ throw new Exception("reserved word " + "\"" + word + "\" not allowed")
+ else word
+ }
+
+ /*override def toVarName(name: String): String = {
+ name match {
+ case _ if (reservedWords.contains(name)) => escapeReservedWord(name)
+ case _ => typeMapping.getOrElse(name, name)
+ }
+ capitalize(name)
+ }
+
+ def capitalize(s: String) = {
+ s(0).toUpper + s.substring(1, s.length).toLowerCase
+ }*/
+
+ // supporting classes
+ override def supportingFiles =
+ List(
+ ("apiInvoker.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiInvoker.java"),
+ ("apiException.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiException.java"),
+ ("Newtonsoft.Json.dll", "generated-code/csharp/bin", "Newtonsoft.Json.dll"),
+ ("compile.mustache", "generated-code/csharp", "compile.bat"))
+}
\ No newline at end of file