Update the Asp.Net core server generator to support Asp.net Core 2.1 (#1008)

* Update the .net core sdk to v2.1 and update the asp.net packages used.

* Upgrade the SwashBuckle Asp.Net Core package to v3.0.0.

* Update the AppSettings json file and add a file used in development.
Also, remove the web.config file.

* Update the program template to use the web host builder class.

* Update the startup class to use the Asp.Net 2.1 paradigms.

* Update the launch settings json file.

* Update the controller template to derive from the ControllerBase class as aposed to Controller.

* Add the SwashBuckle annotations package.

* Add the SwashBuckle.AspNetCore.Annotations namespace to the controller template.

* Update the Startup template to add comments to the Configuration property and an env parameter to the Configure method.

* Update the startup class so we don't need to inject the hosting environment.

* Update the program class to have hte recommended CreateWebHostBuilder method from asp.net core 2.1.

* Update the asp.net core pet store sample server.

* add back aspnetcore 2.0 template via option

* remove web.config for aspnet core 2.1
This commit is contained in:
Sean Farrow 2018-09-12 11:42:16 +01:00 committed by William Cheng
parent 3d4c3c545b
commit 59ad12183f
75 changed files with 1098 additions and 49 deletions

View File

@ -28,6 +28,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.lang.IllegalArgumentException;
import java.net.URL;
import java.util.Arrays;
import java.util.Locale;
@ -38,6 +39,7 @@ import static java.util.UUID.randomUUID;
public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
public static final String USE_SWASHBUCKLE = "useSwashbuckle";
public static final String ASPNET_CORE_VERSION = "aspnetCoreVersion";
private String packageGuid = "{" + randomUUID().toString().toUpperCase(Locale.ROOT) + "}";
@ -47,7 +49,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
private boolean useSwashbuckle = true;
protected int serverPort = 8080;
protected String serverHost = "0.0.0.0";
protected String aspnetCoreVersion= "2.1"; // default to 2.1
public AspNetCoreServerCodegen() {
super();
@ -57,6 +59,8 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("controller.mustache", ".cs");
embeddedTemplateDir = templateDir = "aspnetcore/2.1";
// contextually reserved words
// NOTE: C# uses camel cased reserved words, while models are title cased. We don't want lowercase comparisons.
reservedWords.addAll(
@ -82,6 +86,10 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
CodegenConstants.SOURCE_FOLDER_DESC,
sourceFolder);
addOption(ASPNET_CORE_VERSION,
"ASP.NET Core version: 2.1 (default), 2.0 (deprecated)",
aspnetCoreVersion);
// CLI Switches
addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC,
@ -102,6 +110,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
addSwitch(USE_SWASHBUCKLE,
"Uses the Swashbuckle.AspNetCore NuGet package for documentation.",
useSwashbuckle);
}
@Override
@ -118,6 +127,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
public String getHelp() {
return "Generates an ASP.NET Core Web API server.";
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
super.preprocessOpenAPI(openAPI);
@ -141,6 +151,11 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
additionalProperties.put(USE_SWASHBUCKLE, useSwashbuckle);
}
// determine the ASP.NET core version setting
if (additionalProperties.containsKey(ASPNET_CORE_VERSION)) {
setAspnetCoreVersion((String) additionalProperties.get(ASPNET_CORE_VERSION));
}
additionalProperties.put("dockerTag", packageName.toLowerCase(Locale.ROOT));
apiPackage = packageName + ".Controllers";
@ -148,6 +163,17 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
String packageFolder = sourceFolder + File.separator + packageName;
if ("2.0".equals(aspnetCoreVersion)) {
embeddedTemplateDir = templateDir = "aspnetcore/2.0";
supportingFiles.add(new SupportingFile("web.config", packageFolder, "web.config"));
LOGGER.info("ASP.NET core version: 2.0");
} else if ("2.1".equals(aspnetCoreVersion)) {
// default, do nothing
LOGGER.info("ASP.NET core version: 2.1");
} else {
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"));
@ -159,28 +185,34 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
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("web.config", packageFolder, "web.config"));
supportingFiles.add(new SupportingFile("Project.csproj.mustache", packageFolder, packageName + ".csproj"));
supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", packageFolder + File.separator + "Properties", "launchSettings.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", packageFolder + File.separator + "Filters", "BasePathFilter.cs"));
supportingFiles.add(new SupportingFile("Filters" + File.separator + "GeneratePathParamsValidationFilter.mustache", packageFolder + File.separator + "Filters", "GeneratePathParamsValidationFilter.cs"));
supportingFiles.add(new SupportingFile("Filters" + File.separator + "BasePathFilter.mustache",
packageFolder + File.separator + "Filters", "BasePathFilter.cs"));
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"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "openapi-original.mustache",
packageFolder + File.separator + "wwwroot", "openapi-original.json"));
}
public void setPackageGuid(String packageGuid) {
this.packageGuid = packageGuid;
}
public void setAspnetCoreVersion(String aspnetCoreVersion) {
this.aspnetCoreVersion= aspnetCoreVersion;
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + packageName + File.separator + "Controllers";

View File

@ -0,0 +1,18 @@
FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app
ENV DOTNET_CLI_TELEMETRY_OPTOUT 1
# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "{{packageName}}.dll"]

View File

@ -0,0 +1,50 @@
using System.Linq;
using System.Text.RegularExpressions;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace {{packageName}}.Filters
{
/// <summary>
/// BasePath Document Filter sets BasePath property of Swagger and removes it from the individual URL paths
/// </summary>
public class BasePathFilter : IDocumentFilter
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="basePath">BasePath to remove from Operations</param>
public BasePathFilter(string basePath)
{
BasePath = basePath;
}
/// <summary>
/// Gets the BasePath of the Swagger Doc
/// </summary>
/// <returns>The BasePath of the Swagger Doc</returns>
public string BasePath { get; }
/// <summary>
/// Apply the filter
/// </summary>
/// <param name="swaggerDoc">SwaggerDocument</param>
/// <param name="context">FilterContext</param>
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
swaggerDoc.BasePath = BasePath;
var pathsToModify = swaggerDoc.Paths.Where(p => p.Key.StartsWith(BasePath)).ToList();
foreach (var path in pathsToModify)
{
if (path.Key.StartsWith(BasePath))
{
string newKey = Regex.Replace(path.Key, $"^{BasePath}", string.Empty);
swaggerDoc.Paths.Remove(path.Key);
swaggerDoc.Paths.Add(newKey, path.Value);
}
}
}
}
}

View File

@ -0,0 +1,97 @@
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Controllers;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace {{packageName}}.Filters
{
/// <summary>
/// Path Parameter Validation Rules Filter
/// </summary>
public class GeneratePathParamsValidationFilter : IOperationFilter
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="operation">Operation</param>
/// <param name="context">OperationFilterContext</param>
public void Apply(Operation operation, OperationFilterContext context)
{
var pars = context.ApiDescription.ParameterDescriptions;
foreach (var par in pars)
{
var swaggerParam = operation.Parameters.SingleOrDefault(p => p.Name == par.Name);
var attributes = ((ControllerParameterDescriptor)par.ParameterDescriptor).ParameterInfo.CustomAttributes;
if (attributes != null && attributes.Count() > 0 && swaggerParam != null)
{
// Required - [Required]
var requiredAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(RequiredAttribute));
if (requiredAttr != null)
{
swaggerParam.Required = true;
}
// Regex Pattern [RegularExpression]
var regexAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(RegularExpressionAttribute));
if (regexAttr != null)
{
string regex = (string)regexAttr.ConstructorArguments[0].Value;
if (swaggerParam is NonBodyParameter)
{
((NonBodyParameter)swaggerParam).Pattern = regex;
}
}
// String Length [StringLength]
int? minLenght = null, maxLength = null;
var stringLengthAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(StringLengthAttribute));
if (stringLengthAttr != null)
{
if (stringLengthAttr.NamedArguments.Count == 1)
{
minLenght = (int)stringLengthAttr.NamedArguments.Single(p => p.MemberName == "MinimumLength").TypedValue.Value;
}
maxLength = (int)stringLengthAttr.ConstructorArguments[0].Value;
}
var minLengthAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(MinLengthAttribute));
if (minLengthAttr != null)
{
minLenght = (int)minLengthAttr.ConstructorArguments[0].Value;
}
var maxLengthAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(MaxLengthAttribute));
if (maxLengthAttr != null)
{
maxLength = (int)maxLengthAttr.ConstructorArguments[0].Value;
}
if (swaggerParam is NonBodyParameter)
{
((NonBodyParameter)swaggerParam).MinLength = minLenght;
((NonBodyParameter)swaggerParam).MaxLength = maxLength;
}
// Range [Range]
var rangeAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(RangeAttribute));
if (rangeAttr != null)
{
int rangeMin = (int)rangeAttr.ConstructorArguments[0].Value;
int rangeMax = (int)rangeAttr.ConstructorArguments[1].Value;
if (swaggerParam is NonBodyParameter)
{
((NonBodyParameter)swaggerParam).Minimum = rangeMin;
((NonBodyParameter)swaggerParam).Maximum = rangeMax;
}
}
}
}
}
}
}

View File

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore;
namespace {{packageName}}
{
/// <summary>
/// Program
/// </summary>
public class Program
{
/// <summary>
/// Main
/// </summary>
/// <param name="args"></param>
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
/// <summary>
/// Create the web host builder.
/// </summary>
/// <param name="args"></param>
/// <returns>IWebHostBuilder</returns>
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://0.0.0.0:{{#serverPort}}{{serverPort}}{{/serverPort}}{{^serverPort}}8080{{/serverPort}}/");
}
}

View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<Description>{{packageName}}</Description>
<Copyright>{{packageName}}</Copyright>
<TargetFramework>netcoreapp2.1</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>{{packageName}}</AssemblyName>
<PackageId>{{packageName}}</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
{{#useSwashbuckle}}
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0"/>
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="3.0.0" />
{{/useSwashbuckle}}
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,30 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:61788",
"sslPort": 44301
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebApplication1": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,27 @@
# {{packageName}} - ASP.NET Core 2.0 Server
{{#appDescription}}
{{{appDescription}}}
{{/appDescription}}
## Run
Linux/OS X:
```
sh build.sh
```
Windows:
```
build.bat
```
## Run in Docker
```
cd {{sourceFolder}}/{{packageName}}
docker build -t {{dockerTag}} .
docker run -p 5000:5000 {{dockerTag}}
```

View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27428.2043
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{packageName}}", "{{sourceFolder}}\{{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,120 @@
{{>partial_header}}
using System;
using System.IO;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;{{#useSwashbuckle}}
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using {{packageName}}.Filters;{{/useSwashbuckle}}
namespace {{packageName}}
{
/// <summary>
/// Startup
/// </summary>
public class Startup
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="configuration"></param>
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
/// <summary>
/// The application configuration.
/// </summary>
public IConfiguration Configuration { get; }
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services
.AddMvc()
.SetCompatibilityVersion (CompatibilityVersion.Version_2_1)
.AddJsonOptions(opts =>
{
opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
opts.SerializerSettings.Converters.Add(new StringEnumConverter
{
CamelCaseText = true
});
});{{#useSwashbuckle}}
services
.AddSwaggerGen(c =>
{
c.SwaggerDoc("{{#version}}{{{version}}}{{/version}}{{^version}}v1{{/version}}", new Info
{
Version = "{{#version}}{{{version}}}{{/version}}{{^version}}v1{{/version}}",
Title = "{{#appName}}{{{appName}}}{{/appName}}{{^appName}}{{packageName}}{{/appName}}",
Description = "{{#appName}}{{{appName}}}{{/appName}}{{^appName}}{{packageName}}{{/appName}} (ASP.NET Core 2.0)",
Contact = new Contact()
{
Name = "{{#infoName}}{{{infoName}}}{{/infoName}}{{^infoName}}OpenAPI-Generator Contributors{{/infoName}}",
Url = "{{#infoUrl}}{{{infoUrl}}}{{/infoUrl}}{{^infoUrl}}https://github.com/openapitools/openapi-generator{{/infoUrl}}",
Email = "{{#infoEmail}}{{{infoEmail}}}{{/infoEmail}}"
},
TermsOfService = "{{#termsOfService}}{{{termsOfService}}}{{/termsOfService}}"
});
c.CustomSchemaIds(type => type.FriendlyId(true));
c.DescribeAllEnumsAsStrings();
c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml");
{{#basePathWithoutHost}}
// Sets the basePath property in the Swagger document generated
c.DocumentFilter<BasePathFilter>("{{{basePathWithoutHost}}}");
{{/basePathWithoutHost}}
// Include DataAnnotation attributes on Controller Action parameters as Swagger validation rules (e.g required, pattern, ..)
// Use [ValidateModelState] on Actions to actually validate it in C# as well!
c.OperationFilter<GeneratePathParamsValidationFilter>();
});{{/useSwashbuckle}}
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHttpsRedirection();
app
.UseMvc()
.UseDefaultFiles()
.UseStaticFiles(){{#useSwashbuckle}}
.UseSwagger(c =>
{
c.RouteTemplate = "swagger/{documentName}/openapi.json";
})
.UseSwaggerUI(c =>
{
//TODO: Either use the SwaggerGen generated Swagger contract (generated from C# classes)
c.SwaggerEndpoint("/swagger/{{#version}}{{{version}}}{{/version}}{{^version}}v1{{/version}}/openapi.json", "{{#appName}}{{{appName}}}{{/appName}}{{^appName}}{{packageName}}{{/appName}}");
//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}};
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1 @@
{{#isBodyParam}}[FromBody]{{&dataType}} {{paramName}}{{/isBodyParam}}

View File

@ -0,0 +1,9 @@
:: Generated by: https://openapi-generator.tech
::
@echo off
dotnet restore {{sourceFolder}}\{{packageName}}
dotnet build {{sourceFolder}}\{{packageName}}
echo Now, run the following to start the project: dotnet run -p {{sourceFolder}}\{{packageName}}\{{packageName}}.csproj --launch-profile web.
echo.

View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
#
# Generated by: https://openapi-generator.tech
#
dotnet restore {{sourceFolder}}/{{packageName}}/ && \
dotnet build {{sourceFolder}}/{{packageName}}/ && \
echo "Now, run the following to start the project: dotnet run -p {{sourceFolder}}/{{packageName}}/{{packageName}}.csproj --launch-profile web"

View File

@ -0,0 +1,55 @@
{{>partial_header}}
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;{{#useSwashbuckle}}
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.SwaggerGen;{{/useSwashbuckle}}
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
using {{packageName}}.Attributes;
using {{packageName}}.Models;
namespace {{packageName}}.Controllers
{ {{#operations}}
/// <summary>
/// {{description}}
/// </summary>{{#description}}
[Description("{{description}}")]{{/description}}
public class {{classname}}Controller : ControllerBase
{ {{#operation}}
/// <summary>
/// {{#summary}}{{summary}}{{/summary}}
/// </summary>{{#notes}}
/// <remarks>{{notes}}</remarks>{{/notes}}{{#allParams}}
/// <param name="{{paramName}}">{{description}}</param>{{/allParams}}{{#responses}}
/// <response code="{{code}}">{{message}}</response>{{/responses}}
[{{httpMethod}}]
[Route("{{{basePathWithoutHost}}}{{{path}}}")]
[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}})
{ {{#responses}}
{{#dataType}}
//TODO: Uncomment the next line to return response {{code}} or use other options such as return this.NotFound(), return this.BadRequest(..), ...
// return StatusCode({{code}}, default({{&dataType}}));
{{/dataType}}
{{^dataType}}
//TODO: Uncomment the next line to return response {{code}} or use other options such as return this.NotFound(), return this.BadRequest(..), ...
// return StatusCode({{code}});
{{/dataType}}{{/responses}}
{{#returnType}}
string exampleJson = null;
{{#examples}}
exampleJson = "{{{example}}}";
{{/examples}}
{{#isListCollection}}{{>listReturn}}{{/isListCollection}}{{^isListCollection}}{{#isMapContainer}}{{>mapReturn}}{{/isMapContainer}}{{^isMapContainer}}{{>objectReturn}}{{/isMapContainer}}{{/isListCollection}}
{{!TODO: defaultResponse, examples, auth, consumes, produces, nickname, externalDocs, imports, security}}
//TODO: Change the data returned
return new ObjectResult(example);{{/returnType}}{{^returnType}}
throw new NotImplementedException();{{/returnType}}
}
{{/operation}}
}
{{/operations}}
}

View File

@ -0,0 +1,18 @@
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
/// </summary>
{{#description}}
/// <value>{{{description}}}</value>
{{/description}}
{{#allowableValues}}{{#enumVars}}{{#-first}}{{#isString}}[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]{{/isString}}{{/-first}}{{/enumVars}}{{/allowableValues}}
public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}
{
{{#allowableValues}}{{#enumVars}}
/// <summary>
/// Enum {{name}} for {{{value}}}
/// </summary>
{{#isString}}[EnumMember(Value = "{{{value}}}")]{{/isString}}
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},
{{/-last}}{{/enumVars}}{{/allowableValues}}
}

View File

@ -0,0 +1 @@
{{#isFormParam}}[FromForm]{{#required}}[Required()]{{/required}}{{#pattern}}[RegularExpression("{{{pattern}}}")]{{/pattern}}{{#minLength}}{{#maxLength}}[StringLength({{maxLength}}, MinimumLength={{minLength}}){{/maxLength}}{{/minLength}}{{#minLength}}{{^maxLength}} [MinLength({{minLength}})]{{/maxLength}}{{/minLength}}{{^minLength}}{{#maxLength}} [MaxLength({{maxLength}})]{{/maxLength}}{{/minLength}}{{#minimum}}{{#maximum}}[Range({{minimum}}, {{maximum}})]{{/maximum}}{{/minimum}}{{&dataType}} {{paramName}}{{/isFormParam}}

View File

@ -0,0 +1,208 @@
PID
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
bower_components/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt

View File

@ -0,0 +1 @@
{{#isHeaderParam}}[FromHeader]{{#required}}[Required()]{{/required}}{{#pattern}}[RegularExpression("{{{pattern}}}")]{{/pattern}}{{#minLength}}{{#maxLength}}[StringLength({{maxLength}}, MinimumLength={{minLength}}){{/maxLength}}{{/minLength}}{{#minLength}}{{^maxLength}} [MinLength({{minLength}})]{{/maxLength}}{{/minLength}}{{^minLength}}{{#maxLength}} [MaxLength({{maxLength}})]{{/maxLength}}{{/minLength}}{{#minimum}}{{#maximum}}[Range({{minimum}}, {{maximum}})]{{/maximum}}{{/minimum}}{{&dataType}} {{paramName}}{{/isHeaderParam}}

View File

@ -0,0 +1,4 @@
var example = exampleJson != null
? JsonConvert.DeserializeObject<{{returnContainer}}<{{#returnType}}{{{returnType}}}{{/returnType}}>>(exampleJson)
: Enumerable.Empty<{{#returnType}}{{{returnType}}}{{/returnType}}>();

View File

@ -0,0 +1,4 @@
var example = exampleJson != null
? JsonConvert.DeserializeObject<Dictionary<{{#returnType}}{{{returnType}}}{{/returnType}}>>(exampleJson)
: new Dictionary<{{#returnType}}{{{returnType}}}{{/returnType}}>();

View File

@ -0,0 +1,136 @@
{{>partial_header}}
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
{{#models}}
{{#model}}
namespace {{packageName}}.Models
{ {{#isEnum}}{{>enumClass}}{{/isEnum}}{{^isEnum}}
/// <summary>
/// {{description}}
/// </summary>
[DataContract]
public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}}IEquatable<{{classname}}>
{ {{#vars}}{{#isEnum}}{{>enumClass}}{{/isEnum}}{{#items.isEnum}}{{#items}}{{>enumClass}}{{/items}}{{/items.isEnum}}
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
/// </summary>
{{#description}}
/// <value>{{description}}</value>
{{/description}}
{{#required}}
[Required]
{{/required}}
[DataMember(Name="{{baseName}}")]
{{#isEnum}}
public {{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}?{{/isContainer}}{{/isEnum}} {{name}} { get; set; }
{{/isEnum}}
{{^isEnum}}
public {{{dataType}}} {{name}} { get; {{#isReadOnly}}private {{/isReadOnly}}set; }
{{/isEnum}}
{{#hasMore}}
{{/hasMore}}
{{/vars}}
/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
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();
}
/// <summary>
/// Returns the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public {{#parent}}{{^isMapModel}}{{^isArrayModel}}new {{/isArrayModel}}{{/isMapModel}}{{/parent}}string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
/// <summary>
/// Returns true if objects are equal
/// </summary>
/// <param name="obj">Object to be compared</param>
/// <returns>Boolean</returns>
public override bool Equals(object obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals(({{classname}})obj);
}
/// <summary>
/// Returns true if {{classname}} instances are equal
/// </summary>
/// <param name="other">Instance of {{classname}} to be compared</param>
/// <returns>Boolean</returns>
public bool Equals({{classname}} other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return {{#vars}}{{#isNotContainer}}
(
{{name}} == other.{{name}} ||
{{name}} != null &&
{{name}}.Equals(other.{{name}})
){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{^isNotContainer}}
(
{{name}} == other.{{name}} ||
{{name}} != null &&
{{name}}.SequenceEqual(other.{{name}})
){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{/vars}}{{^vars}}false{{/vars}};
}
/// <summary>
/// Gets the hash code
/// </summary>
/// <returns>Hash code</returns>
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
{{#vars}}
if ({{name}} != null)
hashCode = hashCode * 59 + {{name}}.GetHashCode();
{{/vars}}
return hashCode;
}
}
#region Operators
#pragma warning disable 1591
public static bool operator ==({{classname}} left, {{classname}} right)
{
return Equals(left, right);
}
public static bool operator !=({{classname}} left, {{classname}} right)
{
return !Equals(left, right);
}
#pragma warning restore 1591
#endregion Operators
}
{{/isEnum}}
{{/model}}
{{/models}}
}

View File

@ -0,0 +1,4 @@
var example = exampleJson != null
? JsonConvert.DeserializeObject<{{#returnType}}{{{returnType}}}{{/returnType}}>(exampleJson)
: default({{#returnType}}{{{returnType}}}{{/returnType}});

View File

@ -0,0 +1,13 @@
/*
{{#appName}}
* {{{appName}}}
*
{{/appName}}
{{#appDescription}}
* {{{appDescription}}}
*
{{/appDescription}}
* {{#version}}OpenAPI spec version: {{{version}}}{{/version}}
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
* Generated by: https://openapi-generator.tech
*/

View File

@ -0,0 +1 @@
{{#isPathParam}}[FromRoute]{{#required}}[Required]{{/required}}{{#pattern}}[RegularExpression("{{{pattern}}}")]{{/pattern}}{{#minLength}}{{#maxLength}}[StringLength({{maxLength}}, MinimumLength={{minLength}}){{/maxLength}}{{/minLength}}{{#minLength}}{{^maxLength}} [MinLength({{minLength}})]{{/maxLength}}{{/minLength}}{{^minLength}}{{#maxLength}} [MaxLength({{maxLength}})]{{/maxLength}}{{/minLength}}{{#minimum}}{{#maximum}}[Range({{minimum}}, {{maximum}})]{{/maximum}}{{/minimum}}{{&dataType}} {{paramName}}{{/isPathParam}}

View File

@ -0,0 +1 @@
{{#isQueryParam}}[FromQuery]{{#required}}[Required()]{{/required}}{{#pattern}}[RegularExpression("{{{pattern}}}")]{{/pattern}}{{#minLength}}{{#maxLength}}[StringLength({{maxLength}}, MinimumLength={{minLength}}){{/maxLength}}{{/minLength}}{{#minLength}}{{^maxLength}} [MinLength({{minLength}})]{{/maxLength}}{{/minLength}}{{^minLength}}{{#maxLength}} [MaxLength({{maxLength}})]{{/maxLength}}{{/minLength}}{{#minimum}}{{#maximum}}[Range({{minimum}}, {{maximum}})]{{/maximum}}{{/minimum}}{{&dataType}} {{paramName}}{{/isQueryParam}}

View File

@ -0,0 +1 @@
{{!TODO: Need iterable tags object...}}{{#tags}}, Tags = new[] { {{/tags}}"{{#tags}}{{tag}} {{/tags}}"{{#tags}} }{{/tags}}

View File

@ -0,0 +1,61 @@
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace {{packageName}}.Attributes
{
/// <summary>
/// Model state validation attribute
/// </summary>
public class ValidateModelStateAttribute : ActionFilterAttribute
{
/// <summary>
/// Called before the action method is invoked
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuting(ActionExecutingContext context)
{
// Per https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/
var descriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (descriptor != null)
{
foreach (var parameter in descriptor.MethodInfo.GetParameters())
{
object args = null;
if (context.ActionArguments.ContainsKey(parameter.Name))
{
args = context.ActionArguments[parameter.Name];
}
ValidateAttributes(parameter, args, context.ModelState);
}
}
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
private void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState)
{
foreach (var attributeData in parameter.CustomAttributes)
{
var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType);
var validationAttribute = attributeInstance as ValidationAttribute;
if (validationAttribute != null)
{
var isValid = validationAttribute.IsValid(args);
if (!isValid)
{
modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name));
}
}
}
}
}
}

View File

@ -0,0 +1,42 @@
# Welcome to ASP.NET 5 Preview
We've made some big updates in this release, so its **important** that you spend a few minutes to learn whats new.
ASP.NET 5 has been rearchitected to make it **lean** and **composable**. It's fully **open source** and available on [GitHub](http://go.microsoft.com/fwlink/?LinkID=517854).
Your new project automatically takes advantage of modern client-side utilities like [Bower](http://go.microsoft.com/fwlink/?LinkId=518004) and [npm](http://go.microsoft.com/fwlink/?LinkId=518005) (to add client-side libraries) and [Gulp](http://go.microsoft.com/fwlink/?LinkId=518007) (for client-side build and automation tasks).
We hope you enjoy the new capabilities in ASP.NET 5 and Visual Studio 2015.
The ASP.NET Team
### You've created a new ASP.NET 5 project. [Learn what's new](http://go.microsoft.com/fwlink/?LinkId=518016)
### This application consists of:
* Sample pages using ASP.NET MVC 6
* [Gulp](http://go.microsoft.com/fwlink/?LinkId=518007) and [Bower](http://go.microsoft.com/fwlink/?LinkId=518004) for managing client-side resources
* Theming using [Bootstrap](http://go.microsoft.com/fwlink/?LinkID=398939)
#### NEW CONCEPTS
* [The 'wwwroot' explained](http://go.microsoft.com/fwlink/?LinkId=518008)
* [Configuration in ASP.NET 5](http://go.microsoft.com/fwlink/?LinkId=518012)
* [Dependency Injection](http://go.microsoft.com/fwlink/?LinkId=518013)
* [Razor TagHelpers](http://go.microsoft.com/fwlink/?LinkId=518014)
* [Manage client packages using Gulp](http://go.microsoft.com/fwlink/?LinkID=517849)
* [Develop on different platforms](http://go.microsoft.com/fwlink/?LinkID=517850)
#### CUSTOMIZE APP
* [Add Controllers and Views](http://go.microsoft.com/fwlink/?LinkID=398600)
* [Add Data using EntityFramework](http://go.microsoft.com/fwlink/?LinkID=398602)
* [Add Authentication using Identity](http://go.microsoft.com/fwlink/?LinkID=398603)
* [Add real time support using SignalR](http://go.microsoft.com/fwlink/?LinkID=398606)
* [Add Class library](http://go.microsoft.com/fwlink/?LinkID=398604)
* [Add Web APIs with MVC 6](http://go.microsoft.com/fwlink/?LinkId=518009)
* [Add client packages using Bower](http://go.microsoft.com/fwlink/?LinkID=517848)
#### DEPLOY
* [Run your app locally](http://go.microsoft.com/fwlink/?LinkID=517851)
* [Run your app on ASP.NET Core 5](http://go.microsoft.com/fwlink/?LinkID=517852)
* [Run commands in your 'project.json'](http://go.microsoft.com/fwlink/?LinkID=517853)
* [Publish to Microsoft Azure Web Sites](http://go.microsoft.com/fwlink/?LinkID=398609)
* [Publish to the file system](http://go.microsoft.com/fwlink/?LinkId=518019)
We would love to hear your [feedback](http://go.microsoft.com/fwlink/?LinkId=518015)

View File

@ -0,0 +1 @@
<meta http-equiv="refresh" content="0;URL='./swagger/'" />

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false"/>
</system.webServer>
</configuration>

View File

@ -1 +1 @@
3.0.0-SNAPSHOT
3.3.0-SNAPSHOT

View File

@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.SwaggerGen;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
@ -22,7 +23,7 @@ namespace Org.OpenAPITools.Controllers
/// <summary>
///
/// </summary>
public class PetApiController : Controller
public class PetApiController : ControllerBase
{
/// <summary>
/// Add a new pet to the store

View File

@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.SwaggerGen;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
@ -22,7 +23,7 @@ namespace Org.OpenAPITools.Controllers
/// <summary>
///
/// </summary>
public class StoreApiController : Controller
public class StoreApiController : ControllerBase
{
/// <summary>
/// Delete purchase order by ID

View File

@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.SwaggerGen;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
@ -22,7 +23,7 @@ namespace Org.OpenAPITools.Controllers
/// <summary>
///
/// </summary>
public class UserApiController : Controller
public class UserApiController : ControllerBase
{
/// <summary>
/// Create user

View File

@ -2,17 +2,16 @@
<PropertyGroup>
<Description>Org.OpenAPITools</Description>
<Copyright>Org.OpenAPITools</Copyright>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netcoreapp2.1</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>Org.OpenAPITools</AssemblyName>
<PackageId>Org.OpenAPITools</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.2" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0"/>
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />

View File

@ -14,18 +14,17 @@ namespace Org.OpenAPITools
/// <param name="args"></param>
public static void Main(string[] args)
{
BuildWebHost(args).Run();
CreateWebHostBuilder(args).Build().Run();
}
/// <summary>
/// Build Web Host
/// Create the web host builder.
/// </summary>
/// <param name="args"></param>
/// <returns>Webhost</returns>
public static IWebHost BuildWebHost(string[] args) =>
/// <returns>IWebHostBuilder</returns>
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://0.0.0.0:8080/")
.Build();
.UseUrls("http://0.0.0.0:8080/");
}
}

View File

@ -1,25 +1,27 @@
{
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:50352/",
"sslPort": 0
"applicationUrl": "http://localhost:61788",
"sslPort": 44301
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger/",
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"web": {
"WebApplication1": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000/swagger/",
"launchUrl": "api/values",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}

View File

@ -10,8 +10,10 @@
using System;
using System.IO;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Converters;
@ -27,20 +29,20 @@ namespace Org.OpenAPITools
/// </summary>
public class Startup
{
private readonly IHostingEnvironment _hostingEnv;
private readonly IConfiguration _configuration;
/// <summary>
/// Constructor
/// </summary>
/// <param name="env"></param>
/// <param name="configuration"></param>
public Startup(IHostingEnvironment env, IConfiguration configuration)
public Startup(IConfiguration configuration)
{
_hostingEnv = env;
_configuration = configuration;
Configuration = configuration;
}
/// <summary>
/// The application configuration.
/// </summary>
public IConfiguration Configuration { get; }
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
@ -50,6 +52,7 @@ namespace Org.OpenAPITools
// Add framework services.
services
.AddMvc()
.SetCompatibilityVersion (CompatibilityVersion.Version_2_1)
.AddJsonOptions(opts =>
{
opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
@ -77,7 +80,7 @@ namespace Org.OpenAPITools
});
c.CustomSchemaIds(type => type.FriendlyId(true));
c.DescribeAllEnumsAsStrings();
c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{_hostingEnv.ApplicationName}.xml");
c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml");
// Sets the basePath property in the Swagger document generated
c.DocumentFilter<BasePathFilter>("/v2");
@ -91,8 +94,9 @@ namespace Org.OpenAPITools
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
public void Configure(IApplicationBuilder app)
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHttpsRedirection();
app
.UseMvc()
.UseDefaultFiles()
@ -110,14 +114,13 @@ namespace Org.OpenAPITools
// c.SwaggerEndpoint("/openapi-original.json", "OpenAPI Petstore Original");
});
if (_hostingEnv.IsDevelopment())
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//TODO: Enable production exception handling (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling)
// app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
}
}

View File

@ -1,10 +1,8 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Information",
"System": "Information",
"Microsoft": "Information"
"Default": "Warning"
}
}
},
"AllowedHosts": "*"
}

View File

@ -104,6 +104,7 @@
"in" : "query",
"description" : "Status values that need to be considered for filter",
"required" : true,
"style" : "form",
"explode" : false,
"schema" : {
"type" : "array",
@ -157,6 +158,7 @@
"in" : "query",
"description" : "Tags to filter by",
"required" : true,
"style" : "form",
"explode" : false,
"schema" : {
"type" : "array",