diff --git a/docs/generators/aspnetcore.md b/docs/generators/aspnetcore.md index a864c9e7024..387832c1ab2 100644 --- a/docs/generators/aspnetcore.md +++ b/docs/generators/aspnetcore.md @@ -16,14 +16,19 @@ sidebar_label: aspnetcore |packageVersion|C# package version.| |1.0.0| |packageGuid|The GUID that will be associated with the C# project| |null| |sourceFolder|source folder for generated code| |src| -|compatibilityVersion|ASP.Net Core CompatibilityVersion| |Version_2_1| -|aspnetCoreVersion|ASP.NET Core version: 2.2 (default), 2.1, 2.0 (deprecated)| |2.2| +|compatibilityVersion|ASP.Net Core CompatibilityVersion| |Version_2_2| +|aspnetCoreVersion|ASP.NET Core version: 3.0 (preview4 only), 2.2, 2.1, 2.0 (deprecated)| |2.2| +|swashbuckleVersion|Swashbucke version: 3.0.0, 4.0.0| |3.0.0| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |useDateTimeOffset|Use DateTimeOffset to model date-time properties| |false| |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| |isLibrary|Is the build a library| |false| +|useFrameworkReference|Use frameworkReference for ASP.NET Core 3.0+ and PackageReference ASP.NET Core 2.2 or earlier.| |false| +|useNewtonsoft|Uses the Newtonsoft JSON library.| |true| +|newtonsoftVersion|Version for Microsoft.AspNetCore.Mvc.NewtonsoftJson for ASP.NET Core 3.0+| |3.0.0-preview5-19227-01| +|useDefaultRouting|Use default routing for the ASP.NET Core version. For 3.0 turn off default because it is not yet supported.| |true| |classModifier|Class Modifier can be empty, abstract| || |operationModifier|Operation Modifier can be virtual, abstract or partial| |virtual| |buildTarget|Target to build an application or library| |program| 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 8ffa5e4a6d9..ae3ed7e12da 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 @@ -38,6 +38,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { public static final String USE_SWASHBUCKLE = "useSwashbuckle"; public static final String ASPNET_CORE_VERSION = "aspnetCoreVersion"; + public static final String SWASHBUCKLE_VERSION = "swashbuckleVersion"; public static final String CLASS_MODIFIER = "classModifier"; public static final String OPERATION_MODIFIER = "operationModifier"; public static final String OPERATION_IS_ASYNC = "operationIsAsync"; @@ -51,6 +52,10 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { public static final String SDK_LIB = "Microsoft.NET.Sdk"; public static final String COMPATIBILITY_VERSION = "compatibilityVersion"; public static final String IS_LIBRARY = "isLibrary"; + public static final String USE_FRAMEWORK_REFERENCE = "useFrameworkReference"; + public static final String USE_NEWTONSOFT = "useNewtonsoft"; + public static final String USE_DEFAULT_ROUTING = "useDefaultRouting"; + public static final String NEWTONSOFT_VERSION = "newtonsoftVersion"; private String packageGuid = "{" + randomUUID().toString().toUpperCase(Locale.ROOT) + "}"; @@ -60,18 +65,23 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { private boolean useSwashbuckle = true; protected int serverPort = 8080; protected String serverHost = "0.0.0.0"; - protected CliOption aspnetCoreVersion = new CliOption(ASPNET_CORE_VERSION, "ASP.NET Core version: 2.2 (default), 2.1, 2.0 (deprecated)"); + protected CliOption swashbuckleVersion = new CliOption(SWASHBUCKLE_VERSION, "Swashbucke version: 3.0.0, 4.0.0"); ; // default to 2.1 + protected CliOption aspnetCoreVersion = new CliOption(ASPNET_CORE_VERSION, "ASP.NET Core version: 3.0 (preview4 only), 2.2, 2.1, 2.0 (deprecated)"); private CliOption classModifier = new CliOption(CLASS_MODIFIER, "Class Modifier can be empty, abstract"); private CliOption operationModifier = new CliOption(OPERATION_MODIFIER, "Operation Modifier can be virtual, abstract or partial"); private CliOption modelClassModifier = new CliOption(MODEL_CLASS_MODIFIER, "Model Class Modifier can be nothing or partial"); private boolean generateBody = true; private CliOption buildTarget = new CliOption("buildTarget", "Target to build an application or library"); private String projectSdk = SDK_WEB; - private String compatibilityVersion = "Version_2_1"; + private String compatibilityVersion = "Version_2_2"; private boolean operationIsAsync = false; private boolean operationResultTask = false; private boolean isLibrary = false; + private boolean useFrameworkReference = false; + private boolean useNewtonsoft = true; + private boolean useDefaultRouting = true; + private String newtonsoftVersion = "3.0.0-preview5-19227-01"; public AspNetCoreServerCodegen() { super(); @@ -146,10 +156,18 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { aspnetCoreVersion.addEnum("2.0", "ASP.NET COre 2.0"); aspnetCoreVersion.addEnum("2.1", "ASP.NET Core 2.1"); aspnetCoreVersion.addEnum("2.2", "ASP.NET Core 2.2"); + aspnetCoreVersion.addEnum("3.0", "ASP.NET Core 3.0"); aspnetCoreVersion.setDefault("2.2"); aspnetCoreVersion.setOptValue(aspnetCoreVersion.getDefault()); addOption(aspnetCoreVersion.getOpt(), aspnetCoreVersion.getDescription(), aspnetCoreVersion.getOptValue()); + swashbuckleVersion.addEnum("3.0.0", "Swashbuckle 3.0.0"); + swashbuckleVersion.addEnum("4.0.0", "Swashbuckle 4.0.0"); + swashbuckleVersion.addEnum("5.0.0", "Swashbuckle 5.0.0"); + swashbuckleVersion.setDefault("3.0.0"); + swashbuckleVersion.setOptValue(swashbuckleVersion.getDefault()); + addOption(swashbuckleVersion.getOpt(), swashbuckleVersion.getDescription(), swashbuckleVersion.getOptValue()); + // CLI Switches addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC, @@ -175,6 +193,23 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { "Is the build a library", isLibrary); + addSwitch(USE_FRAMEWORK_REFERENCE, + "Use frameworkReference for ASP.NET Core 3.0+ and PackageReference ASP.NET Core 2.2 or earlier.", + useFrameworkReference); + + addSwitch(USE_NEWTONSOFT, + "Uses the Newtonsoft JSON library.", + useNewtonsoft); + + addOption(NEWTONSOFT_VERSION, + "Version for Microsoft.AspNetCore.Mvc.NewtonsoftJson for ASP.NET Core 3.0+", + newtonsoftVersion); + + + addSwitch(USE_DEFAULT_ROUTING, + "Use default routing for the ASP.NET Core version. For 3.0 turn off default because it is not yet supported.", + useDefaultRouting); + classModifier.addEnum("", "Keep class default with no modifier"); classModifier.addEnum("abstract", "Make class abstract"); classModifier.setDefault(""); @@ -246,6 +281,11 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { } additionalProperties.put("packageGuid", packageGuid); + if (!additionalProperties.containsKey(NEWTONSOFT_VERSION)) { + additionalProperties.put(NEWTONSOFT_VERSION, newtonsoftVersion); + } else { + newtonsoftVersion = (String)additionalProperties.get(NEWTONSOFT_VERSION); + } // CHeck for the modifiers etc. // The order of the checks is important. @@ -275,6 +315,10 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { // determine the ASP.NET core version setting setAspnetCoreVersion(packageFolder); + setSwashbuckleVersion(); + setIsFramework(); + setUseNewtonsoft(); + setUseEndpointRouting(); supportingFiles.add(new SupportingFile("build.sh.mustache", "", "build.sh")); supportingFiles.add(new SupportingFile("build.bat.mustache", "", "build.bat")); @@ -479,10 +523,66 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { if (isLibrary) { operationIsAsync = false; additionalProperties.put(OPERATION_IS_ASYNC, operationIsAsync); - } else if (additionalProperties.containsKey(OPERATION_IS_ASYNC)) { + } else if (additionalProperties.containsKey(OPERATION_IS_ASYNC)) { operationIsAsync = convertPropertyToBooleanAndWriteBack(OPERATION_IS_ASYNC); } else { additionalProperties.put(OPERATION_IS_ASYNC, operationIsAsync); } } + + private void setIsFramework() { + if (aspnetCoreVersion.getOptValue().startsWith("3.")) {// default, do nothing + LOGGER.warn("ASP.NET core version is " + aspnetCoreVersion.getOptValue() + " so changing to use frameworkReference instead of packageReference "); + useFrameworkReference = true; + additionalProperties.put(USE_FRAMEWORK_REFERENCE, useFrameworkReference); + } else { + if (additionalProperties.containsKey(USE_FRAMEWORK_REFERENCE)) { + useFrameworkReference = convertPropertyToBooleanAndWriteBack(USE_FRAMEWORK_REFERENCE); + } else { + additionalProperties.put(USE_FRAMEWORK_REFERENCE, useFrameworkReference); + } + } + + } + + private void setUseNewtonsoft() { + if (aspnetCoreVersion.getOptValue().startsWith("2.")) { + LOGGER.warn("ASP.NET core version is " + aspnetCoreVersion.getOptValue() + " so staying on default json library."); + useNewtonsoft = false; + additionalProperties.put(USE_NEWTONSOFT, useNewtonsoft); + } else { + if (additionalProperties.containsKey(USE_NEWTONSOFT)) { + useNewtonsoft = convertPropertyToBooleanAndWriteBack(USE_NEWTONSOFT); + } else { + additionalProperties.put(USE_NEWTONSOFT, useNewtonsoft); + } + } + } + + private void setUseEndpointRouting() { + if (aspnetCoreVersion.getOptValue().startsWith("3.")) { + LOGGER.warn("ASP.NET core version is " + aspnetCoreVersion.getOptValue() + " so switching to old style endpoint routing."); + useDefaultRouting = false; + additionalProperties.put(USE_DEFAULT_ROUTING, useDefaultRouting); + } else { + if (additionalProperties.containsKey(USE_DEFAULT_ROUTING)) { + useDefaultRouting = convertPropertyToBooleanAndWriteBack(USE_DEFAULT_ROUTING); + } else { + additionalProperties.put(USE_DEFAULT_ROUTING, useDefaultRouting); + } + } + } + + private void setSwashbuckleVersion() { + setCliOption(swashbuckleVersion); + + if (aspnetCoreVersion.getOptValue().startsWith("3.")) { + LOGGER.warn("ASP.NET core version is " + aspnetCoreVersion.getOptValue() + " so changing default Swashbuckle version to 4.0.0."); + swashbuckleVersion.setOptValue("4.0.0"); + additionalProperties.put(SWASHBUCKLE_VERSION, swashbuckleVersion.getOptValue()); + } else { + // default, do nothing + LOGGER.info("Swashbuckle version: " + swashbuckleVersion.getOptValue()); + } + } } 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 3714e878dc4..a7b6b35bd78 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 @@ -12,10 +12,20 @@ {{packageName}} +{{#useFrameworkReference}} +{{#isLibrary}} + +{{/isLibrary}} +{{/useFrameworkReference}} +{{^useFrameworkReference}} +{{/useFrameworkReference}} +{{#useNewtonsoft}} + +{{/useNewtonsoft}} {{#useSwashbuckle}} - - + + {{/useSwashbuckle}} diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Startup.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Startup.mustache index 5883d72bcae..98fb1fe23e6 100644 --- a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Startup.mustache +++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Startup.mustache @@ -60,16 +60,16 @@ namespace {{packageName}} // Add framework services. services - .AddMvc() + .AddMvc({{^useDefaultRoutng}}opts => opts.EnableEndpointRouting = false{{/useDefaultRoutng}}) {{#compatibilityVersion}} .SetCompatibilityVersion(CompatibilityVersion.{{compatibilityVersion}}) {{/compatibilityVersion}} - .AddJsonOptions(opts => + .{{#useNewtonsoft}}AddNewtonsoftJson{{/useNewtonsoft}}{{^useNewtonsoft}}AddJsonOptions{{/useNewtonsoft}}(opts => { opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); opts.SerializerSettings.Converters.Add(new StringEnumConverter { - CamelCaseText = true + {{#useNewtonsoft}}NamingStrategy = new CamelCaseNamingStrategy(){{/useNewtonsoft}}{{^useNewtonsoft}}CamelCaseText = true{{/useNewtonsoft}} }); }); {{#useSwashbuckle}} @@ -127,7 +127,12 @@ namespace {{packageName}} //TODO: Or alternatively use the original Swagger contract that's included in the static files // c.SwaggerEndpoint("/openapi-original.json", "{{#appName}}{{{appName}}}{{/appName}}{{^appName}}{{packageName}}{{/appName}} Original"); - }){{/useSwashbuckle}}; + }){{/useSwashbuckle}};{{^useDefaultRoutng}} + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + });{{/useDefaultRoutng}} if (env.IsDevelopment()) {