Swagger working but with removed api versioning system and a lot of other shit removed during diagnosis. Revert to this commit to go that route.
This commit is contained in:
@@ -62,23 +62,31 @@ namespace AyaNova
|
||||
{
|
||||
_log.LogDebug("BOOT: initializing services...");
|
||||
|
||||
//dotnet 3.x added this wasn't here before
|
||||
services.AddControllers();
|
||||
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
|
||||
});
|
||||
|
||||
//Server state service for shutting people out of api
|
||||
_log.LogDebug("BOOT: init ApiServerState service");
|
||||
services.AddSingleton(new AyaNova.Api.ControllerHelpers.ApiServerState());
|
||||
|
||||
|
||||
//dotnet 3 commented this out, new project doesn't have it
|
||||
//Init mvc
|
||||
_log.LogDebug("BOOT: init MVC Core service");
|
||||
var mvc = services.AddMvcCore();
|
||||
_log.LogDebug("BOOT: add json service");
|
||||
mvc.AddNewtonsoftJson();
|
||||
// _log.LogDebug("BOOT: init MVC Core service");
|
||||
// var mvc = services.AddMvcCore();
|
||||
// _log.LogDebug("BOOT: add json service");
|
||||
// mvc.AddNewtonsoftJson();
|
||||
|
||||
|
||||
// add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
|
||||
// note: the specified format code will format the version as "'v'major[.minor][-status]"
|
||||
_log.LogDebug("BOOT: init ApiExplorer service");
|
||||
services.AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV");
|
||||
// services.AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV");
|
||||
|
||||
_log.LogDebug("BOOT: ensuring user and backup folders exist and are separate locations...");
|
||||
FileUtil.EnsureUserAndUtilityFoldersExistAndAreNotIdentical(_hostingEnvironment.ContentRootPath);
|
||||
@@ -135,44 +143,45 @@ namespace AyaNova
|
||||
#endregion
|
||||
|
||||
_log.LogDebug("BOOT: init ApiVersioning service");
|
||||
// services.AddApiVersioning(o => o.ReportApiVersions = true);
|
||||
services
|
||||
.AddApiVersioning(options =>
|
||||
{
|
||||
options.AssumeDefaultVersionWhenUnspecified = true;
|
||||
options.DefaultApiVersion = Microsoft.AspNetCore.Mvc.ApiVersion.Parse("8.0");
|
||||
options.ReportApiVersions = true;
|
||||
});
|
||||
// services
|
||||
// .AddApiVersioning(options =>
|
||||
// {
|
||||
// options.AssumeDefaultVersionWhenUnspecified = true;
|
||||
// options.DefaultApiVersion = Microsoft.AspNetCore.Mvc.ApiVersion.Parse("8.0");
|
||||
// options.ReportApiVersions = true;
|
||||
// });
|
||||
|
||||
|
||||
// Add service and create Policy with options
|
||||
_log.LogDebug("BOOT: init CORS service");
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("CorsPolicy",
|
||||
builder => builder.AllowAnyOrigin()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader()
|
||||
.AllowCredentials());
|
||||
});
|
||||
//v3 commented out to try to figure out why the swagger docs aren't generating and may be superfluous
|
||||
// // Add service and create Policy with options
|
||||
// _log.LogDebug("BOOT: init CORS service");
|
||||
// services.AddCors(options =>
|
||||
// {
|
||||
// options.AddPolicy("CorsPolicy",
|
||||
// builder => builder.AllowAnyOrigin()
|
||||
// .AllowAnyMethod()
|
||||
// .AllowAnyHeader()
|
||||
// //.AllowCredentials()
|
||||
// );
|
||||
// });
|
||||
|
||||
|
||||
_log.LogDebug("BOOT: init MVC service");
|
||||
_log.LogDebug("BOOT: init Metrics service");
|
||||
|
||||
|
||||
services.AddMvc(config =>
|
||||
{
|
||||
//was this but needed logging, not certain about the new way of adding so keeping this in case it all goes sideways in testing
|
||||
//config.Filters.Add(typeof(AyaNova.Api.ControllerHelpers.ApiCustomExceptionFilter));
|
||||
config.Filters.Add(new AyaNova.Api.ControllerHelpers.ApiCustomExceptionFilter(AyaNova.Util.ApplicationLogging.LoggerFactory));
|
||||
// services.AddMvc(config =>
|
||||
// {
|
||||
// //was this but needed logging, not certain about the new way of adding so keeping this in case it all goes sideways in testing
|
||||
// //config.Filters.Add(typeof(AyaNova.Api.ControllerHelpers.ApiCustomExceptionFilter));
|
||||
// config.Filters.Add(new AyaNova.Api.ControllerHelpers.ApiCustomExceptionFilter(AyaNova.Util.ApplicationLogging.LoggerFactory));
|
||||
|
||||
}).AddMetrics().AddJsonOptions(options =>
|
||||
{
|
||||
//2019-10-15 - removed this due to fuckery after update, is it required??? Not sure at this point
|
||||
//if metrics have wrong dates then it's important I guess
|
||||
//options.JsonSerializerOptions.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
|
||||
});
|
||||
// }).AddMetrics().AddJsonOptions(options =>
|
||||
// {
|
||||
// //2019-10-15 - removed this due to fuckery after update, is it required??? Not sure at this point
|
||||
// //if metrics have wrong dates then it's important I guess
|
||||
// //options.JsonSerializerOptions.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
|
||||
// });
|
||||
|
||||
|
||||
#region Swagger
|
||||
@@ -181,73 +190,112 @@ namespace AyaNova
|
||||
//https://github.com/domaindrivendev/Swashbuckle.AspNetCore
|
||||
|
||||
_log.LogDebug("BOOT: init API explorer service");
|
||||
services.AddSwaggerGen(
|
||||
c =>
|
||||
{
|
||||
// resolve the IApiVersionDescriptionProvider service
|
||||
// note: that we have to build a temporary service provider here because one has not been created yet
|
||||
var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
|
||||
// services.AddSwaggerGen(c =>
|
||||
// {
|
||||
// c.SwaggerDoc("v8", new OpenApiInfo { Title = "My API", Version = "v8" });
|
||||
// c.OperationFilter<AuthResponsesOperationFilter>();
|
||||
|
||||
// add a swagger document for each discovered API version
|
||||
// note: you might choose to skip or document deprecated API versions differently
|
||||
foreach (var description in provider.ApiVersionDescriptions)
|
||||
{
|
||||
c.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description));
|
||||
}
|
||||
// });
|
||||
// services.AddSwaggerGen(
|
||||
// c =>
|
||||
// {
|
||||
|
||||
// add a custom operation filter which sets default values
|
||||
//Removed because will no longer compile the SwaggerDefaultValues but may be needed, not sure it's all a bit muddled
|
||||
// c.OperationFilter<SwaggerDefaultValues>();
|
||||
|
||||
// integrate xml comments
|
||||
c.IncludeXmlComments(XmlCommentsFilePath);
|
||||
// c.DocInclusionPredicate((docName, apiDesc) =>
|
||||
// {
|
||||
// if (!apiDesc.TryGetMethodInfo(out MethodInfo methodInfo)) return false;
|
||||
|
||||
// // Get the MapToApiVersion attributes of the action
|
||||
// var mapApiVersions = methodInfo
|
||||
// .GetCustomAttributes(true)
|
||||
// .OfType<MapToApiVersionAttribute>()
|
||||
// .SelectMany(attr => attr.Versions);
|
||||
|
||||
// //if it contains MapToApiVersion attributes, then we should check those as the ApiVersion ones are ignored
|
||||
// if (mapApiVersions.Any() && mapApiVersions.Any(v => $"v{v.ToString()}" == docName))
|
||||
// return true;
|
||||
|
||||
// // Get the ApiVersion attributes of the controller
|
||||
// var versions = methodInfo.DeclaringType
|
||||
// .GetCustomAttributes(true)
|
||||
// .OfType<ApiVersionAttribute>()
|
||||
// .SelectMany(attr => attr.Versions);
|
||||
|
||||
// return versions.Any(v => $"v{v.ToString()}" == docName);
|
||||
// });
|
||||
|
||||
|
||||
|
||||
//2019-10-15 - Removed this because apikeyscheme is no longer recognized and it appears it *may* not be necessary... TWT
|
||||
//If I have any issues with bearer tokens in swagger then this is probably necessary but in a new way
|
||||
//this is required to allow authentication when testing secure routes via swagger UI
|
||||
// c.AddSecurityDefinition("Bearer", new ApiKeyScheme
|
||||
// {
|
||||
// Description = "JWT Authorization header using the Bearer scheme. Get your token by logging in via the Auth route then enter it here with the \"Bearer \" prefix. Example: \"Bearer {token}\"",
|
||||
// Name = "Authorization",
|
||||
// In = "header",
|
||||
// Type = "apiKey"
|
||||
// // resolve the IApiVersionDescriptionProvider service
|
||||
// // note: that we have to build a temporary service provider here because one has not been created yet
|
||||
// var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
|
||||
|
||||
// });
|
||||
// // add a swagger document for each discovered API version
|
||||
// // note: you might choose to skip or document deprecated API versions differently
|
||||
// foreach (var description in provider.ApiVersionDescriptions)
|
||||
// {
|
||||
// c.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description));
|
||||
// }
|
||||
|
||||
// // add a custom operation filter which sets default values
|
||||
// // c.OperationFilter<SwaggerDefaultValues>();
|
||||
|
||||
// //test filter WTF?
|
||||
// //c.OperationFilter<AuthResponsesOperationFilter>();
|
||||
|
||||
// // integrate xml comments
|
||||
// c.IncludeXmlComments(XmlCommentsFilePath);
|
||||
|
||||
|
||||
|
||||
// // //2019-10-15 - Removed this because apikeyscheme is no longer recognized and it appears it *may* not be necessary... TWT
|
||||
// // //If I have any issues with bearer tokens in swagger then this is probably necessary but in a new way
|
||||
// // //this is required to allow authentication when testing secure routes via swagger UI
|
||||
// // c.AddSecurityDefinition("Bearer", new ApiKeyScheme
|
||||
// // {
|
||||
// // Description = "JWT Authorization header using the Bearer scheme. Get your token by logging in via the Auth route then enter it here with the \"Bearer \" prefix. Example: \"Bearer {token}\"",
|
||||
// // Name = "Authorization",
|
||||
// // In = "header",
|
||||
// // Type = "apiKey"
|
||||
|
||||
// // });
|
||||
|
||||
|
||||
|
||||
|
||||
//Obsolete way
|
||||
// c.AddSecurityRequirement(new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>
|
||||
// {
|
||||
// { "Bearer", new string[] { } }
|
||||
// });
|
||||
// //Obsolete way
|
||||
// // c.AddSecurityRequirement(new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>
|
||||
// // {
|
||||
// // { "Bearer", new string[] { } }
|
||||
// // });
|
||||
|
||||
//https://stackoverflow.com/questions/56234504/migrating-to-swashbuckle-aspnetcore-version-5
|
||||
//First we define the security scheme
|
||||
c.AddSecurityDefinition("Bearer", //Name the security scheme
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "JWT Authorization header using the Bearer scheme.",
|
||||
Type = SecuritySchemeType.Http, //We set the scheme type to http since we're using bearer authentication
|
||||
Scheme = "bearer" //The name of the HTTP Authorization scheme to be used in the Authorization header. In this case "bearer".
|
||||
});
|
||||
// //https://stackoverflow.com/questions/56234504/migrating-to-swashbuckle-aspnetcore-version-5
|
||||
// //First we define the security scheme
|
||||
// c.AddSecurityDefinition("Bearer", //Name the security scheme
|
||||
// new OpenApiSecurityScheme
|
||||
// {
|
||||
// Description = "JWT Authorization header using the Bearer scheme.",
|
||||
// Type = SecuritySchemeType.Http, //We set the scheme type to http since we're using bearer authentication
|
||||
// Scheme = "bearer" //The name of the HTTP Authorization scheme to be used in the Authorization header. In this case "bearer".
|
||||
// });
|
||||
|
||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
|
||||
{
|
||||
new OpenApiSecurityScheme{
|
||||
Reference = new OpenApiReference{
|
||||
Id = "Bearer", //The name of the previously defined security scheme.
|
||||
Type = ReferenceType.SecurityScheme
|
||||
}
|
||||
},new List<string>()
|
||||
}
|
||||
});
|
||||
// c.AddSecurityRequirement(new OpenApiSecurityRequirement{
|
||||
// {
|
||||
// new OpenApiSecurityScheme{
|
||||
// Reference = new OpenApiReference{
|
||||
// Id = "Bearer", //The name of the previously defined security scheme.
|
||||
// Type = ReferenceType.SecurityScheme
|
||||
// }
|
||||
// },new List<string>()
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
});
|
||||
// //https://github.com/domaindrivendev/Swashbuckle.AspNetCore
|
||||
// //ARGGHHHHHHHH!!!!!
|
||||
|
||||
|
||||
// });
|
||||
|
||||
|
||||
#endregion
|
||||
@@ -319,10 +367,19 @@ namespace AyaNova
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
//
|
||||
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IWebHostEnvironment env,
|
||||
AyContext dbContext, IApiVersionDescriptionProvider provider, AyaNova.Api.ControllerHelpers.ApiServerState apiServerState, IServiceProvider serviceProvider)
|
||||
AyContext dbContext, AyaNova.Api.ControllerHelpers.ApiServerState apiServerState, IServiceProvider serviceProvider)
|
||||
{
|
||||
//This was in constructor right after dbcontext: IApiVersionDescriptionProvider provider,
|
||||
_log.LogDebug("BOOT: configuring request pipeline...");
|
||||
|
||||
//dotnet3 test added
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
//This is in new templates generated for webapi but it errors out for me so removing it for now
|
||||
// app.UseHttpsRedirection();
|
||||
|
||||
//Store a reference to the dependency injection service for static classes
|
||||
ServiceProviderProvider.Provider = app.ApplicationServices;
|
||||
@@ -337,26 +394,15 @@ namespace AyaNova
|
||||
_log.LogDebug("BOOT: pipeline - static files");
|
||||
app.UseDefaultFiles();
|
||||
app.UseStaticFiles();
|
||||
//Might need the following if the page doesn't update in the client properly
|
||||
//however the vue build process will automatically uniquify each build file names so maybe not required
|
||||
// app.UseStaticFiles(new StaticFileOptions
|
||||
// {
|
||||
// OnPrepareResponse = context =>
|
||||
// {
|
||||
// if (context.File.Name == "index.html")
|
||||
// {
|
||||
// context.Context.Response.Headers.Add("Cache-Control", "no-cache, no-store");
|
||||
// context.Context.Response.Headers.Add("Expires", "-1");
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
#endregion
|
||||
|
||||
_log.LogDebug("BOOT: pipeline - ROUTING");
|
||||
app.UseRouting();//this wasn't here for 2.2 but added for 3.0, needs to come before the stuff after
|
||||
|
||||
_log.LogDebug("BOOT: pipeline - CORS");
|
||||
app.UseCors("CorsPolicy");
|
||||
//v3test
|
||||
// _log.LogDebug("BOOT: pipeline - CORS");
|
||||
// app.UseCors("CorsPolicy");
|
||||
|
||||
|
||||
#region AUTH / ROLES
|
||||
@@ -364,6 +410,9 @@ namespace AyaNova
|
||||
//Use authentication middleware
|
||||
app.UseAuthentication();
|
||||
|
||||
_log.LogDebug("BOOT: pipeline - authorization");
|
||||
app.UseAuthorization();
|
||||
|
||||
//Custom middleware to get user roles and put them into the request so
|
||||
//they can be authorized in routes.
|
||||
app.Use(async (context, next) =>
|
||||
@@ -395,28 +444,46 @@ namespace AyaNova
|
||||
|
||||
#endregion
|
||||
|
||||
//According to https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-2.2&tabs=visual-studio#migrate-startupconfigure
|
||||
_log.LogDebug("BOOT: pipeline - ENDPOINTS");
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
|
||||
|
||||
#region SWAGGER
|
||||
|
||||
_log.LogDebug("BOOT: pipeline - api explorer");
|
||||
// Enable middleware to serve generated Swagger as a JSON endpoint.
|
||||
app.UseSwagger();
|
||||
// // Enable middleware to serve generated Swagger as a JSON endpoint.
|
||||
// app.UseSwagger();
|
||||
|
||||
// app.UseSwaggerUI(c =>
|
||||
// {
|
||||
// // build a swagger endpoint for each discovered API version
|
||||
// foreach (var description in provider.ApiVersionDescriptions)
|
||||
// {
|
||||
// c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
|
||||
// }
|
||||
|
||||
// //clean up the swagger explorer UI page and remove the branding
|
||||
// //via our own css
|
||||
// //NOTE: this broke when updated to v2.x of swagger and it can be fixed according to docs:
|
||||
// //https://github.com/domaindrivendev/Swashbuckle.AspNetCore#inject-custom-css
|
||||
// // c.InjectStylesheet("/api/sw.css");
|
||||
|
||||
// c.DefaultModelsExpandDepth(-1);
|
||||
// c.DocumentTitle = "AyaNova API explorer";
|
||||
// c.RoutePrefix = "api-docs";
|
||||
|
||||
// });
|
||||
|
||||
app.UseSwagger();
|
||||
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
// build a swagger endpoint for each discovered API version
|
||||
foreach (var description in provider.ApiVersionDescriptions)
|
||||
{
|
||||
c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
|
||||
}
|
||||
|
||||
//clean up the swagger explorer UI page and remove the branding
|
||||
//via our own css
|
||||
//NOTE: this broke when updated to v2.x of swagger and it can be fixed according to docs:
|
||||
//https://github.com/domaindrivendev/Swashbuckle.AspNetCore#inject-custom-css
|
||||
// c.InjectStylesheet("/api/sw.css");
|
||||
|
||||
c.DefaultModelsExpandDepth(-1);
|
||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
||||
c.DefaultModelsExpandDepth(-1);
|
||||
c.DocumentTitle = "AyaNova API explorer";
|
||||
c.RoutePrefix = "api-docs";
|
||||
});
|
||||
@@ -427,21 +494,12 @@ namespace AyaNova
|
||||
|
||||
|
||||
|
||||
//According to https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-2.2&tabs=visual-studio#migrate-startupconfigure
|
||||
//replace use mvc with use endpoints
|
||||
// //USE MVC
|
||||
// _log.LogDebug("BOOT: pipeline - MVC");
|
||||
// app.UseMvc();
|
||||
_log.LogDebug("BOOT: pipeline - ENDPOINTS");
|
||||
app.UseEndpoints(endpoints => {
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
|
||||
// ******************************************************************
|
||||
// ******************** TESTING WIPE DB *****************************
|
||||
//
|
||||
//Set this to true to wipe the db and reinstall a trial license and re-seed the data
|
||||
var TESTING_REFRESH_DB = true;//#######################################################################################
|
||||
var TESTING_REFRESH_DB = false;//#######################################################################################
|
||||
|
||||
#if (DEBUG)
|
||||
//TESTING
|
||||
@@ -524,33 +582,33 @@ _log.LogDebug("BOOT: pipeline - ENDPOINTS");
|
||||
|
||||
#region Swagger and API Versioning utilities
|
||||
|
||||
static string XmlCommentsFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
//Obsolete, used new method: https://developers.de/blogs/holger_vetter/archive/2017/06/30/swagger-includexmlcomments-platformservices-obsolete-replacement.aspx
|
||||
//var basePath = PlatformServices.Default.Application.ApplicationBasePath;
|
||||
var basePath = AppContext.BaseDirectory;
|
||||
var fileName = typeof(Startup).GetTypeInfo().Assembly.GetName().Name + ".xml";
|
||||
return Path.Combine(basePath, fileName);
|
||||
}
|
||||
}
|
||||
// static string XmlCommentsFilePath
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// //Obsolete, used new method: https://developers.de/blogs/holger_vetter/archive/2017/06/30/swagger-includexmlcomments-platformservices-obsolete-replacement.aspx
|
||||
// //var basePath = PlatformServices.Default.Application.ApplicationBasePath;
|
||||
// var basePath = AppContext.BaseDirectory;
|
||||
// var fileName = typeof(Startup).GetTypeInfo().Assembly.GetName().Name + ".xml";
|
||||
// return Path.Combine(basePath, fileName);
|
||||
// }
|
||||
// }
|
||||
|
||||
static Microsoft.OpenApi.Models.OpenApiInfo CreateInfoForApiVersion(ApiVersionDescription description)
|
||||
{
|
||||
var info = new Microsoft.OpenApi.Models.OpenApiInfo()
|
||||
{
|
||||
Title = $"AyaNova API {description.ApiVersion}",
|
||||
Version = description.ApiVersion.ToString()
|
||||
};
|
||||
// static Microsoft.OpenApi.Models.OpenApiInfo CreateInfoForApiVersion(ApiVersionDescription description)
|
||||
// {
|
||||
// var info = new Microsoft.OpenApi.Models.OpenApiInfo()
|
||||
// {
|
||||
// Title = $"AyaNova API {description.ApiVersion}",
|
||||
// Version = description.ApiVersion.ToString()
|
||||
// };
|
||||
|
||||
if (description.IsDeprecated)
|
||||
{
|
||||
info.Description += " This API version has been deprecated.";
|
||||
}
|
||||
// if (description.IsDeprecated)
|
||||
// {
|
||||
// info.Description += " This API version has been deprecated.";
|
||||
// }
|
||||
|
||||
return info;
|
||||
}
|
||||
// return info;
|
||||
// }
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user