diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java
new file mode 100644
index 000000000000..029f46ed1b50
--- /dev/null
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java
@@ -0,0 +1,127 @@
+package io.swagger.codegen.languages;
+
+import io.swagger.codegen.CodegenConstants;
+import io.swagger.codegen.CodegenOperation;
+import io.swagger.codegen.CodegenType;
+import io.swagger.codegen.SupportingFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.Arrays;
+
+public class NancyFXServerCodegen extends AbstractCSharpCodegen {
+
+ protected String sourceFolder = "src" + File.separator + packageName;
+ protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase() + "}";
+
+ @SuppressWarnings("hiding")
+ protected Logger LOGGER = LoggerFactory.getLogger(NancyFXServerCodegen.class);
+
+ public NancyFXServerCodegen() {
+ super();
+
+ outputFolder = "generated-code" + File.separator + this.getName();
+
+ modelTemplateFiles.put("model.mustache", ".cs");
+ apiTemplateFiles.put("api.mustache", ".cs");
+
+ // contextually reserved words
+ setReservedWordsLowerCase(
+ Arrays.asList("var", "async", "await", "dynamic", "yield")
+ );
+
+ cliOptions.clear();
+
+ // CLI options
+ addOption(CodegenConstants.PACKAGE_NAME,
+ "C# package name (convention: Title.Case).",
+ this.packageName);
+
+ addOption(CodegenConstants.PACKAGE_VERSION,
+ "C# package version.",
+ this.packageVersion);
+
+ addOption(CodegenConstants.SOURCE_FOLDER,
+ CodegenConstants.SOURCE_FOLDER_DESC,
+ sourceFolder);
+
+ // CLI Switches
+ addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
+ CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC,
+ this.sortParamsByRequiredFlag);
+
+ addSwitch(CodegenConstants.OPTIONAL_PROJECT_FILE,
+ CodegenConstants.OPTIONAL_PROJECT_FILE_DESC,
+ this.optionalProjectFileFlag);
+
+ addSwitch(CodegenConstants.USE_DATETIME_OFFSET,
+ CodegenConstants.USE_DATETIME_OFFSET_DESC,
+ this.useDateTimeOffsetFlag);
+
+ addSwitch(CodegenConstants.USE_COLLECTION,
+ CodegenConstants.USE_COLLECTION_DESC,
+ this.useCollection);
+
+ addSwitch(CodegenConstants.RETURN_ICOLLECTION,
+ CodegenConstants.RETURN_ICOLLECTION_DESC,
+ this.returnICollection);
+ }
+
+ @Override
+ public CodegenType getTag() {
+ return CodegenType.SERVER;
+ }
+
+ @Override
+ public String getName() {
+ return "nancyfx";
+ }
+
+ @Override
+ public String getHelp() {
+ return "Generates a NancyFX Web API server.";
+ }
+
+ @Override
+ public void processOpts() {
+ super.processOpts();
+
+ String packageFolder = sourceFolder + File.separator + packageName;
+ apiPackage = packageName + ".Api";
+ modelPackage = packageName + ".Models";
+
+ if (optionalProjectFileFlag) {
+ supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
+ supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder, packageName + ".csproj"));
+ }
+ additionalProperties.put("packageGuid", packageGuid);
+ }
+
+ @Override
+ public String apiFileFolder() {
+ return outputFolder + File.separator + sourceFolder + File.separator + "Api";
+ }
+
+ @Override
+ public String modelFileFolder() {
+ return outputFolder + File.separator + sourceFolder + File.separator + "Models";
+ }
+
+ @Override
+ protected void processOperation(CodegenOperation operation) {
+ super.processOperation(operation);
+
+ // HACK: Unlikely in the wild, but we need to clean operation paths for MVC Routing
+ if (operation.path != null) {
+ String original = operation.path;
+ operation.path = operation.path.replace("?", "/");
+ if (!original.equals(operation.path)) {
+ LOGGER.warn("Normalized " + original + " to " + operation.path + ". Please verify generated source.");
+ }
+ }
+
+ // Converts, for example, PUT to HttpPut for controller attributes
+ operation.httpMethod = "Http" + operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase();
+ }
+}
diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig
index f0d0fde5e576..868922a6ddf8 100644
--- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig
+++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig
@@ -16,6 +16,7 @@ io.swagger.codegen.languages.JavascriptClientCodegen
io.swagger.codegen.languages.JavascriptClosureAngularClientCodegen
io.swagger.codegen.languages.JavaJerseyServerCodegen
io.swagger.codegen.languages.JMeterCodegen
+io.swagger.codegen.languages.NancyFXServerCodegen
io.swagger.codegen.languages.NodeJSServerCodegen
io.swagger.codegen.languages.ObjcClientCodegen
io.swagger.codegen.languages.PerlClientCodegen
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache
new file mode 100644
index 000000000000..3a753d150f6b
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache
@@ -0,0 +1,54 @@
+
+
+
+ Debug
+ AnyCPU
+ {{packageGuid}}
+ Library
+ Properties
+ {{packageTitle}}
+ {{packageTitle}}
+ {{^supportsUWP}}
+ {{targetFramework}}
+ {{/supportsUWP}}
+ {{#supportsUWP}}
+ UAP
+ 10.0.10240.0
+ 10.0.10240.0
+ 14
+ {{/supportsUWP}}
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache
new file mode 100644
index 000000000000..7f2d34e366ea
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache
@@ -0,0 +1,25 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+VisualStudioVersion = 12.0.0.0
+MinimumVisualStudioVersion = 10.0.0.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{packageName}}", "src\{{packageName}}\{{packageName}}.csproj", "{{packageGuid}}"
+EndProject
+Global
+GlobalSection(SolutionConfigurationPlatforms) = preSolution
+Debug|Any CPU = Debug|Any CPU
+Release|Any CPU = Release|Any CPU
+EndGlobalSection
+GlobalSection(ProjectConfigurationPlatforms) = postSolution
+{{packageGuid}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+{{packageGuid}}.Debug|Any CPU.Build.0 = Debug|Any CPU
+{{packageGuid}}.Release|Any CPU.ActiveCfg = Release|Any CPU
+{{packageGuid}}.Release|Any CPU.Build.0 = Release|Any CPU
+{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.Build.0 = Debug|Any CPU
+{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.ActiveCfg = Release|Any CPU
+{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.Build.0 = Release|Any CPU
+EndGlobalSection
+GlobalSection(SolutionProperties) = preSolution
+HideSolutionNode = FALSE
+EndGlobalSection
+EndGlobal
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache
new file mode 100644
index 000000000000..e9c5c919898f
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Mvc;
+using Newtonsoft.Json;
+using Swashbuckle.SwaggerGen.Annotations;
+using {{packageName}}.Models;
+
+namespace {{packageName}}.Controllers
+{ {{#operations}}
+ ///
+ /// {{description}}
+ /// {{#description}}{{#basePath}}
+ [Route("{{basePath}}")]
+ {{/basePath}}[Description("{{description}}")]{{/description}}
+ public class {{classname}}Controller : Controller
+ { {{#operation}}
+
+ ///
+ /// {{#summary}}{{summary}}{{/summary}}
+ ///
+ {{#notes}}/// {{notes}}{{/notes}}{{#allParams}}
+ /// {{description}}{{/allParams}}{{#responses}}
+ /// {{message}}{{/responses}}
+ [{{httpMethod}}]
+ [Route("{{path}}")]
+ [SwaggerOperation("{{operationId}}")]{{#returnType}}
+ [SwaggerResponse(200, type: typeof({{&returnType}}))]{{/returnType}}
+ public {{#returnType}}IActionResult{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
+ { {{#returnType}}
+ string exampleJson = null;
+ {{#isListCollection}}{{>listReturn}}{{/isListCollection}}{{^isListCollection}}{{#isMapContainer}}{{>mapReturn}}{{/isMapContainer}}{{^isMapContainer}}{{>objectReturn}}{{/isMapContainer}}{{/isListCollection}}
+ {{!TODO: defaultResponse, examples, auth, consumes, produces, nickname, externalDocs, imports, security}}
+ return new ObjectResult(example);{{/returnType}}{{^returnType}}
+ throw new NotImplementedException();{{/returnType}}
+ }
+{{/operation}}
+ }
+{{/operations}}
+}
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache
new file mode 100644
index 000000000000..02b0fa1d2dea
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache
@@ -0,0 +1 @@
+{{#isBodyParam}}[FromBody]{{&dataType}} {{paramName}}{{/isBodyParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache
new file mode 100644
index 000000000000..1e743e1e4c73
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache
@@ -0,0 +1 @@
+{{#isFormParam}}[FromForm]{{&dataType}} {{paramName}}{{/isFormParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache
new file mode 100644
index 000000000000..e61cadb11315
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache
@@ -0,0 +1 @@
+{{#isHeaderParam}}[FromHeader]{{&dataType}} {{paramName}}{{/isHeaderParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache
new file mode 100644
index 000000000000..d609e67148c2
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache
@@ -0,0 +1,4 @@
+
+ var example = exampleJson != null
+ ? JsonConvert.DeserializeObject<{{returnContainer}}<{{#returnType}}{{{returnType}}}{{/returnType}}>>(exampleJson)
+ : Enumerable.Empty<{{#returnType}}{{{returnType}}}{{/returnType}}>();
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache
new file mode 100644
index 000000000000..856fb1b3507c
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache
@@ -0,0 +1,4 @@
+
+ var example = exampleJson != null
+ ? JsonConvert.DeserializeObject>(exampleJson)
+ : new Dictionary<{{#returnType}}{{{returnType}}}{{/returnType}}>();
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache
new file mode 100644
index 000000000000..08aaed01f3db
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache
@@ -0,0 +1,154 @@
+using System;
+using System.Linq;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+
+{{#models}}
+{{#model}}
+namespace {{packageName}}.Models
+{
+ ///
+ /// {{description}}
+ ///
+ public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+{{#vars}} /// {{#description}}{{description}}{{/description}}{{^description}}{{name}}{{/description}}{{#required}} (required){{/required}}{{#defaultValue}} (default to {{defaultValue}}){{/defaultValue}}.
+{{/vars}}
+ public {{classname}}({{#vars}}{{{datatype}}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}})
+ {
+ {{#vars}}{{#required}}// to ensure "{{name}}" is required (not null)
+ if ({{name}} == null)
+ {
+ throw new InvalidDataException("{{name}} is a required property for {{classname}} and cannot be null");
+ }
+ else
+ {
+ this.{{name}} = {{name}};
+ }
+ {{/required}}{{/vars}}{{#vars}}{{^required}}{{#defaultValue}}// use default value if no "{{name}}" provided
+ if ({{name}} == null)
+ {
+ this.{{name}} = {{{defaultValue}}};
+ }
+ else
+ {
+ this.{{name}} = {{name}};
+ }
+ {{/defaultValue}}{{^defaultValue}}this.{{name}} = {{name}};
+ {{/defaultValue}}{{/required}}{{/vars}}
+ }
+
+ {{#vars}}
+ ///
+ /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
+ /// {{#description}}
+ /// {{{description}}}{{/description}}
+ public {{{datatype}}} {{name}} { get; set; }
+
+ {{/vars}}
+
+ ///
+ /// Returns the string presentation of the object
+ ///
+ /// String presentation of the object
+ 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();
+ }
+
+ ///
+ /// Returns the JSON string presentation of the object
+ ///
+ /// JSON string presentation of the object
+ public {{#parent}} new {{/parent}}string ToJson()
+ {
+ return JsonConvert.SerializeObject(this, Formatting.Indented);
+ }
+
+ ///
+ /// Returns true if objects are equal
+ ///
+ /// Object to be compared
+ /// Boolean
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals(({{classname}})obj);
+ }
+
+ ///
+ /// Returns true if {{classname}} instances are equal
+ ///
+ /// Instance of {{classname}} to be compared
+ /// Boolean
+ public bool Equals({{classname}} other)
+ {
+
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+
+ return {{#vars}}{{#isNotContainer}}
+ (
+ this.{{name}} == other.{{name}} ||
+ this.{{name}} != null &&
+ this.{{name}}.Equals(other.{{name}})
+ ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{^isNotContainer}}
+ (
+ this.{{name}} == other.{{name}} ||
+ this.{{name}} != null &&
+ this.{{name}}.SequenceEqual(other.{{name}})
+ ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{/vars}}{{^vars}}false{{/vars}};
+ }
+
+ ///
+ /// Gets the hash code
+ ///
+ /// Hash code
+ public override int GetHashCode()
+ {
+ // credit: http://stackoverflow.com/a/263416/677735
+ unchecked // Overflow is fine, just wrap
+ {
+ int hash = 41;
+ // Suitable nullity checks etc, of course :)
+ {{#vars}}
+ if (this.{{name}} != null)
+ hash = hash * 59 + this.{{name}}.GetHashCode();
+ {{/vars}}
+ return hash;
+ }
+ }
+
+ #region Operators
+
+ public static bool operator ==({{classname}} left, {{classname}} right)
+ {
+ return Equals(left, right);
+ }
+
+ public static bool operator !=({{classname}} left, {{classname}} right)
+ {
+ return !Equals(left, right);
+ }
+
+ #endregion Operators
+
+ }
+{{/model}}
+{{/models}}
+}
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache
new file mode 100644
index 000000000000..4059a61ac0b8
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache
@@ -0,0 +1,4 @@
+
+ var example = exampleJson != null
+ ? JsonConvert.DeserializeObject<{{#returnType}}{{{returnType}}}{{/returnType}}>(exampleJson)
+ : default({{#returnType}}{{{returnType}}}{{/returnType}});
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache
new file mode 100644
index 000000000000..5aa27eb4cb3e
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache
@@ -0,0 +1 @@
+{{#isPathParam}}[FromRoute]{{&dataType}} {{paramName}}{{/isPathParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache
new file mode 100644
index 000000000000..42ce87a2b7fe
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache
@@ -0,0 +1 @@
+{{#isQueryParam}}[FromQuery]{{&dataType}} {{paramName}}{{/isQueryParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache
new file mode 100644
index 000000000000..c97df19949e6
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache
@@ -0,0 +1 @@
+{{!TODO: Need iterable tags object...}}{{#tags}}, Tags = new[] { {{/tags}}"{{#tags}}{{tag}} {{/tags}}"{{#tags}} }{{/tags}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java
new file mode 100644
index 000000000000..e24df8847138
--- /dev/null
+++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java
@@ -0,0 +1,35 @@
+package io.swagger.codegen.options;
+
+import com.google.common.collect.ImmutableMap;
+import io.swagger.codegen.CodegenConstants;
+
+import java.util.Map;
+
+public class NancyFXServerOptionsProvider implements OptionsProvider {
+ public static final String PACKAGE_NAME_VALUE = "swagger_server_nancyfx";
+ public static final String PACKAGE_VERSION_VALUE = "1.0.0-SNAPSHOT";
+ public static final String SOURCE_FOLDER_VALUE = "src_nancyfx";
+
+ @Override
+ public String getLanguage() {
+ return "nancyfx";
+ }
+
+ @Override
+ public Map createOptions() {
+ ImmutableMap.Builder builder = new ImmutableMap.Builder();
+ return builder.put(CodegenConstants.PACKAGE_NAME, PACKAGE_NAME_VALUE)
+ .put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE)
+ .put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE)
+ .put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true")
+ .put(CodegenConstants.USE_DATETIME_OFFSET, "true")
+ .put(CodegenConstants.USE_COLLECTION, "false")
+ .put(CodegenConstants.RETURN_ICOLLECTION, "false")
+ .build();
+ }
+
+ @Override
+ public boolean isServer() {
+ return true;
+ }
+}