diff --git a/docs/generators/aspnetcore.md b/docs/generators/aspnetcore.md index 07a55944c0f..63c1d810c11 100644 --- a/docs/generators/aspnetcore.md +++ b/docs/generators/aspnetcore.md @@ -7,6 +7,11 @@ sidebar_label: aspnetcore | Option | Description | Values | Default | | ------ | ----------- | ------ | ------- | +|licenseUrl|The URL of the license| |http://localhost| +|licenseName|The name of the license| |NoLicense| +|packageCopyright|Specifies an AssemblyCopyright for the .NET Framework global assembly attributes stored in the AssemblyInfo file.| |No Copyright| +|packageAuthors|Specifies Authors property in the .NET Core project file.| |OpenAPI| +|packageTitle|Specifies an AssemblyTitle for the .NET Framework global assembly attributes stored in the AssemblyInfo file.| |OpenAPI Library| |packageName|C# package name (convention: Title.Case).| |Org.OpenAPITools| |packageVersion|C# package version.| |1.0.0| |packageGuid|The GUID that will be associated with the C# project| |null| @@ -17,3 +22,7 @@ sidebar_label: aspnetcore |useCollection|Deserialize array types to Collection<T> instead of List<T>.| |false| |returnICollection|Return ICollection<T> instead of the concrete type.| |false| |useSwashbuckle|Uses the Swashbuckle.AspNetCore NuGet package for documentation.| |true| +|classModifier|Class modifiers such as abstract or partial| || +|operationModifier|Operation modifiers such as virtual or abstract.| |virtual| +|generateBody|Generates method body.| |true| +|buildTarget|Target the build for a program or library.| |program| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java index 11f4fdb0443..3a1b061f6c3 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java @@ -48,6 +48,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co protected String modelPropertyNaming = CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.PascalCase.name(); + protected String licenseUrl = "http://localhost"; + protected String licenseName = "NoLicense"; + protected String packageVersion = "1.0.0"; protected String packageName = "Org.OpenAPITools"; protected String packageTitle = "OpenAPI Library"; @@ -226,6 +229,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co } } + @Override public void processOpts() { super.processOpts(); @@ -235,6 +239,19 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI)."); } + // License info + if (additionalProperties.containsKey(CodegenConstants.LICENSE_URL)) { + setLicenseUrl((String) additionalProperties.get(CodegenConstants.LICENSE_URL)); + } else { + additionalProperties.put(CodegenConstants.LICENSE_URL, this.licenseUrl); + } + + if (additionalProperties.containsKey(CodegenConstants.LICENSE_NAME)) { + setLicenseName((String) additionalProperties.get(CodegenConstants.LICENSE_NAME)); + } else { + additionalProperties.put(CodegenConstants.LICENSE_NAME, this.licenseName); + } + // {{packageVersion}} if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) { setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION)); @@ -927,6 +944,10 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co return toModelName(name) + "Tests"; } + public void setLicenseUrl(String licenseUrl) {this.licenseUrl = licenseUrl;} + + public void setLicenseName(String licenseName) {this.licenseName = licenseName;} + public void setPackageName(String packageName) { this.packageName = packageName; } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AspNetCoreServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AspNetCoreServerCodegen.java index 424f879dfde..fe4bce79ae3 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AspNetCoreServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AspNetCoreServerCodegen.java @@ -39,6 +39,14 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { public static final String USE_SWASHBUCKLE = "useSwashbuckle"; public static final String ASPNET_CORE_VERSION = "aspnetCoreVersion"; + public static final String CLASS_MODIFIER = "classModifier"; + public static final String OPERATION_MODIFIER = "operationModifier"; + public static final String GENERATE_BODY = "generateBody"; + public static final String BUILD_TARGET = "buildTarget"; + + public static final String PROJECT_SDK = "projectSdk"; + public static final String SDK_WEB = "Microsoft.NET.Sdk.Web"; + public static final String SDK_LIB = "Microsoft.NET.Sdk"; private String packageGuid = "{" + randomUUID().toString().toUpperCase(Locale.ROOT) + "}"; @@ -49,6 +57,12 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { protected int serverPort = 8080; protected String serverHost = "0.0.0.0"; protected String aspnetCoreVersion= "2.1"; // default to 2.1 + // TODO Make next two enums toensure fixed list. + private String classModifier = ""; + private String operationModifier = "virtual"; + private boolean generateBody = true; + private String buildTarget = "program"; + private String projectSdk = SDK_WEB; public AspNetCoreServerCodegen() { super(); @@ -69,6 +83,26 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { cliOptions.clear(); // CLI options + addOption(CodegenConstants.LICENSE_URL, + CodegenConstants.LICENSE_URL_DESC, + licenseUrl); + + addOption(CodegenConstants.LICENSE_NAME, + CodegenConstants.LICENSE_NAME_DESC, + licenseName); + + addOption(CodegenConstants.PACKAGE_COPYRIGHT, + CodegenConstants.PACKAGE_COPYRIGHT_DESC, + packageCopyright); + + addOption(CodegenConstants.PACKAGE_AUTHORS, + CodegenConstants.PACKAGE_AUTHORS_DESC, + packageAuthors); + + addOption(CodegenConstants.PACKAGE_TITLE, + CodegenConstants.PACKAGE_TITLE_DESC, + packageTitle); + addOption(CodegenConstants.PACKAGE_NAME, "C# package name (convention: Title.Case).", packageName); @@ -110,6 +144,22 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { "Uses the Swashbuckle.AspNetCore NuGet package for documentation.", useSwashbuckle); + addOption(CLASS_MODIFIER, + "Class modifiers such as abstract or partial", + classModifier); + + addOption(OPERATION_MODIFIER, + "Operation modifiers such as virtual or abstract.", + operationModifier); + + addSwitch(GENERATE_BODY, + "Generates method body.", + generateBody); + + addOption(BUILD_TARGET, + "Target the build for a program or library.", + buildTarget); + } @Override @@ -138,6 +188,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { @Override public void processOpts() { super.processOpts(); + boolean isLibrary = false; if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_GUID)) { setPackageGuid((String) additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_GUID)); @@ -155,6 +206,50 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { setAspnetCoreVersion((String) additionalProperties.get(ASPNET_CORE_VERSION)); } + // CHeck for class modifier if not present set the default value. + if (additionalProperties.containsKey(CLASS_MODIFIER)) { + classModifier = additionalProperties.get(CLASS_MODIFIER).toString(); + } else { + additionalProperties.put(CLASS_MODIFIER, classModifier); + } + + // TODO Validate modifier values + // If class modifierier is abstract then the methods need to be abstrat too. + if ("abstract".equals(classModifier)) { + operationModifier = classModifier; + additionalProperties.put(OPERATION_MODIFIER, operationModifier); + } + + if (additionalProperties.containsKey(OPERATION_MODIFIER)) { + operationModifier = additionalProperties.get(OPERATION_MODIFIER).toString(); + } else { + additionalProperties.put(OPERATION_MODIFIER, operationModifier); + } + + // TODO Validate modifier values + // If operation modifier is abstract then dont generate any body + if ("abstract".equals(operationModifier)) { + generateBody = false; + additionalProperties.put(GENERATE_BODY, generateBody); + } + if (additionalProperties.containsKey(GENERATE_BODY)) { + generateBody = convertPropertyToBooleanAndWriteBack(GENERATE_BODY); + } else { + additionalProperties.put(GENERATE_BODY, generateBody); + } + + // CHeck for class modifier if not present set the default value. + if (additionalProperties.containsKey(BUILD_TARGET)) { + buildTarget = additionalProperties.get(BUILD_TARGET).toString(); + } else { + additionalProperties.put(BUILD_TARGET, buildTarget); + } + if ("library".equals(buildTarget)) { + isLibrary = true; + projectSdk = SDK_LIB; + } + additionalProperties.put(PROJECT_SDK, projectSdk); + additionalProperties.put("dockerTag", packageName.toLowerCase(Locale.ROOT)); apiPackage = packageName + ".Controllers"; @@ -173,21 +268,53 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { throw new IllegalArgumentException("aspnetCoreVersion must be '2.1', '2.0' but found " + aspnetCoreVersion); } + supportingFiles.add(new SupportingFile("build.sh.mustache", "", "build.sh")); supportingFiles.add(new SupportingFile("build.bat.mustache", "", "build.bat")); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln")); - supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile")); supportingFiles.add(new SupportingFile("gitignore", packageFolder, ".gitignore")); - supportingFiles.add(new SupportingFile("appsettings.json", packageFolder, "appsettings.json")); - - supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs")); - supportingFiles.add(new SupportingFile("Program.mustache", packageFolder, "Program.cs")); supportingFiles.add(new SupportingFile("validateModel.mustache", packageFolder + File.separator + "Attributes", "ValidateModelStateAttribute.cs")); supportingFiles.add(new SupportingFile("Project.csproj.mustache", packageFolder, packageName + ".csproj")); + if (!isLibrary) { + supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile")); + supportingFiles.add(new SupportingFile("appsettings.json", packageFolder, "appsettings.json")); + + supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs")); + supportingFiles.add(new SupportingFile("Program.mustache", packageFolder, "Program.cs")); + supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", + packageFolder + File.separator + "Properties", "launchSettings.json")); + } else { + supportingFiles.add(new SupportingFile("Project.nuspec.mustache", packageFolder, packageName + ".nuspec")); + // wwwroot files. + supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", packageFolder + File.separator + "wwwroot", "README.md")); + supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", packageFolder + File.separator + "wwwroot", "index.html")); + supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", packageFolder + File.separator + "wwwroot", "web.config")); + + supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "openapi-original.mustache", + packageFolder + File.separator + "wwwroot", "openapi-original.json")); + } + supportingFiles.add(new SupportingFile("validateModel.mustache", packageFolder + File.separator + "Attributes", "ValidateModelStateAttribute.cs")); + supportingFiles.add(new SupportingFile("Project.csproj.mustache", packageFolder, packageName + ".csproj")); + if (!isLibrary) { + supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile")); + supportingFiles.add(new SupportingFile("appsettings.json", packageFolder, "appsettings.json")); + + supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs")); + supportingFiles.add(new SupportingFile("Program.mustache", packageFolder, "Program.cs")); + supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", + packageFolder + File.separator + "Properties", "launchSettings.json")); + } else { + supportingFiles.add(new SupportingFile("Project.nuspec.mustache", packageFolder, packageName + ".nuspec")); + // wwwroot files. + supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", packageFolder + File.separator + "wwwroot", "README.md")); + supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", packageFolder + File.separator + "wwwroot", "index.html")); + supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", packageFolder + File.separator + "wwwroot", "web.config")); + + supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "openapi-original.mustache", + packageFolder + File.separator + "wwwroot", "openapi-original.json")); + } - supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", - packageFolder + File.separator + "Properties", "launchSettings.json")); if (useSwashbuckle) { supportingFiles.add(new SupportingFile("Filters" + File.separator + "BasePathFilter.mustache", @@ -195,13 +322,6 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { supportingFiles.add(new SupportingFile("Filters" + File.separator + "GeneratePathParamsValidationFilter.mustache", packageFolder + File.separator + "Filters", "GeneratePathParamsValidationFilter.cs")); } - - supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", packageFolder + File.separator + "wwwroot", "README.md")); - supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", packageFolder + File.separator + "wwwroot", "index.html")); - supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", packageFolder + File.separator + "wwwroot", "web.config")); - - supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "openapi-original.mustache", - packageFolder + File.separator + "wwwroot", "openapi-original.json")); } public void setPackageGuid(String packageGuid) { diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Project.csproj.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Project.csproj.mustache index faa7dbd53b5..0430f24a4a4 100644 --- a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Project.csproj.mustache +++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Project.csproj.mustache @@ -1,4 +1,4 @@ - + {{packageName}} {{packageName}} diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Project.nuspec.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Project.nuspec.mustache new file mode 100644 index 00000000000..03490d71129 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Project.nuspec.mustache @@ -0,0 +1,20 @@ + + + + $id$ + {{packageVersion}} + {{packageTitle}} + {{packageAuthors}} + {{packageAuthors}} + {{licenseUrl}} + + false + {{packageName}} + Summary of changes made in this release of the package. + {{packageCopyright}} + {{packageName}} + + diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/controller.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/controller.mustache index 1805b7d2cc6..57a4f545f4b 100644 --- a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/controller.mustache +++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/controller.mustache @@ -15,7 +15,7 @@ namespace {{packageName}}.Controllers /// {{description}} /// {{#description}} [Description("{{description}}")]{{/description}} - public class {{classname}}Controller : ControllerBase + public {{classModifier}} class {{classname}}Controller : ControllerBase { {{#operation}} /// /// {{#summary}}{{summary}}{{/summary}} @@ -28,7 +28,8 @@ namespace {{packageName}}.Controllers [ValidateModelState]{{#useSwashbuckle}} [SwaggerOperation("{{operationId}}")]{{#responses}}{{#dataType}} [SwaggerResponse(statusCode: {{code}}, type: typeof({{&dataType}}), description: "{{message}}")]{{/dataType}}{{^dataType}}{{/dataType}}{{/responses}}{{/useSwashbuckle}} - public virtual IActionResult {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) + public {{operationModifier}} IActionResult {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) + {{#generateBody}} { {{#responses}} {{#dataType}} //TODO: Uncomment the next line to return response {{code}} or use other options such as return this.NotFound(), return this.BadRequest(..), ... @@ -49,6 +50,10 @@ namespace {{packageName}}.Controllers return new ObjectResult(example);{{/returnType}}{{^returnType}} throw new NotImplementedException();{{/returnType}} } + {{/generateBody}} + {{^generateBody}} + ; + {{/generateBody}} {{/operation}} } {{/operations}} diff --git a/samples/server/petstore/aspnetcore/.openapi-generator/VERSION b/samples/server/petstore/aspnetcore/.openapi-generator/VERSION index afa63656064..94ae9ee1fa8 100644 --- a/samples/server/petstore/aspnetcore/.openapi-generator/VERSION +++ b/samples/server/petstore/aspnetcore/.openapi-generator/VERSION @@ -1 +1 @@ -4.0.0-SNAPSHOT \ No newline at end of file +4.0.0-SNAPSHOT diff --git a/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/PetApi.cs b/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/PetApi.cs index aa08f520afa..8a0d855e30f 100644 --- a/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/PetApi.cs +++ b/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/PetApi.cs @@ -23,7 +23,7 @@ namespace Org.OpenAPITools.Controllers /// /// /// - public class PetApiController : ControllerBase + public class PetApiController : ControllerBase { /// /// Add a new pet to the store diff --git a/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/StoreApi.cs b/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/StoreApi.cs index 4f9ac8f5e18..d6e4720d4c1 100644 --- a/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/StoreApi.cs +++ b/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/StoreApi.cs @@ -23,7 +23,7 @@ namespace Org.OpenAPITools.Controllers /// /// /// - public class StoreApiController : ControllerBase + public class StoreApiController : ControllerBase { /// /// Delete purchase order by ID diff --git a/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/UserApi.cs b/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/UserApi.cs index 85820331a5e..01f3ade7a5b 100644 --- a/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/UserApi.cs +++ b/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/Controllers/UserApi.cs @@ -23,7 +23,7 @@ namespace Org.OpenAPITools.Controllers /// /// /// - public class UserApiController : ControllerBase + public class UserApiController : ControllerBase { /// /// Create user diff --git a/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/wwwroot/openapi-original.json b/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/wwwroot/openapi-original.json index a0a4803cd07..b39e24282ff 100644 --- a/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/wwwroot/openapi-original.json +++ b/samples/server/petstore/aspnetcore/src/Org.OpenAPITools/wwwroot/openapi-original.json @@ -112,8 +112,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "available", - "enum" : [ "available", "pending", "sold" ] + "enum" : [ "available", "pending", "sold" ], + "default" : "available" } } } ],