diff --git a/server/AyaNova/ConfigureSwaggerOptions.cs b/server/AyaNova/ConfigureSwaggerOptions.cs
new file mode 100644
index 00000000..26c7bb33
--- /dev/null
+++ b/server/AyaNova/ConfigureSwaggerOptions.cs
@@ -0,0 +1,54 @@
+namespace AyaNova
+{
+ using Microsoft.AspNetCore.Mvc.ApiExplorer;
+ using Microsoft.Extensions.DependencyInjection;
+ using Microsoft.Extensions.Options;
+ using Microsoft.OpenApi.Models;
+ using Swashbuckle.AspNetCore.SwaggerGen;
+ using System;
+
+ ///
+ /// Configures the Swagger generation options.
+ ///
+ /// This allows API versioning to define a Swagger document per API version after the
+ /// service has been resolved from the service container.
+ public class ConfigureSwaggerOptions : IConfigureOptions
+ {
+ readonly IApiVersionDescriptionProvider provider;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The provider used to generate Swagger documents.
+ public ConfigureSwaggerOptions( IApiVersionDescriptionProvider provider ) => this.provider = provider;
+
+ ///
+ public void Configure( SwaggerGenOptions options )
+ {
+ // 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 )
+ {
+ options.SwaggerDoc( description.GroupName, CreateInfoForApiVersion( description ) );
+ }
+ }
+
+ static OpenApiInfo CreateInfoForApiVersion( ApiVersionDescription description )
+ {
+ var info = new OpenApiInfo()
+ {
+ Title = "AyaNova API",
+ Version = description.ApiVersion.ToString(),
+ Description = "AyaNova service management software API",
+
+ };
+
+ if ( description.IsDeprecated )
+ {
+ info.Description += " This API version has been deprecated.";
+ }
+
+ return info;
+ }
+ }
+}
\ No newline at end of file
diff --git a/server/AyaNova/Controllers/DataFilterController.cs b/server/AyaNova/Controllers/DataFilterController.cs
index 1bb6b6d8..b4450f14 100644
--- a/server/AyaNova/Controllers/DataFilterController.cs
+++ b/server/AyaNova/Controllers/DataFilterController.cs
@@ -15,7 +15,7 @@ using AyaNova.Biz;
namespace AyaNova.Api.Controllers
{
-
+
///
///
///
@@ -95,7 +95,7 @@ namespace AyaNova.Api.Controllers
//Instantiate the business object handler
DataFilterBiz biz = DataFilterBiz.GetBiz(ct, HttpContext);
-
+
var l = await biz.GetPickListAsync(ListKey);
return Ok(ApiOkResponse.Response(l, true));
@@ -154,9 +154,10 @@ namespace AyaNova.Api.Controllers
/// BizAdminFull, InventoryFull, TechFull
///
///
+ /// Automatically filled from route path, no need to specify in body
///
[HttpPost]
- public async Task PostDataFilter([FromBody] DataFilter inObj)
+ public async Task PostDataFilter([FromBody] DataFilter inObj, ApiVersion apiVersion)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
@@ -176,7 +177,7 @@ namespace AyaNova.Api.Controllers
if (o == null)
return BadRequest(new ApiErrorResponse(biz.Errors));
else
- return CreatedAtAction("GetDataFilter", new { id = o.Id }, new ApiCreatedResponse(o));
+ return CreatedAtAction(nameof(DataFilterController.GetDataFilter), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
}
diff --git a/server/AyaNova/Controllers/FormCustomController.cs b/server/AyaNova/Controllers/FormCustomController.cs
index 9a2e17b4..17fa2119 100644
--- a/server/AyaNova/Controllers/FormCustomController.cs
+++ b/server/AyaNova/Controllers/FormCustomController.cs
@@ -227,9 +227,10 @@ namespace AyaNova.Api.Controllers
/// Required roles: BizAdminFull
///
///
+ /// Automatically filled from route path, no need to specify in body
///
[HttpPost]
- public async Task PostFormCustom([FromBody] FormCustom inObj)
+ public async Task PostFormCustom([FromBody] FormCustom inObj, ApiVersion apiVersion)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
@@ -249,7 +250,7 @@ namespace AyaNova.Api.Controllers
if (o == null)
return BadRequest(new ApiErrorResponse(biz.Errors));
else
- return CreatedAtAction("GetFormCustom", new { formkey = o.FormKey }, new ApiCreatedResponse(o));
+ return CreatedAtAction(nameof(FormCustomController.GetFormCustom), new { formkey = o.FormKey, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
}
diff --git a/server/AyaNova/Controllers/LocaleController.cs b/server/AyaNova/Controllers/LocaleController.cs
index c0768c34..169cf925 100644
--- a/server/AyaNova/Controllers/LocaleController.cs
+++ b/server/AyaNova/Controllers/LocaleController.cs
@@ -169,9 +169,10 @@ namespace AyaNova.Api.Controllers
///
///
/// NameIdItem object containing source locale Id and new name
+ /// Automatically filled from route path, no need to specify in body
/// Error response or newly created locale
[HttpPost("Duplicate")]
- public async Task Duplicate([FromBody] NameIdItem inObj)
+ public async Task Duplicate([FromBody] NameIdItem inObj, ApiVersion apiVersion)
{
if (serverState.IsClosed)
{
@@ -191,7 +192,7 @@ namespace AyaNova.Api.Controllers
}
else
{
- return CreatedAtAction("GetLocale", new { id = o.Id }, new ApiCreatedResponse(o));
+ return CreatedAtAction(nameof(LocaleController.GetLocale), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
}
}
diff --git a/server/AyaNova/Controllers/UserController.cs b/server/AyaNova/Controllers/UserController.cs
index ed5920a4..665bc0f8 100644
--- a/server/AyaNova/Controllers/UserController.cs
+++ b/server/AyaNova/Controllers/UserController.cs
@@ -316,9 +316,10 @@ namespace AyaNova.Api.Controllers
///
///
///
+ /// Automatically filled from route path, no need to specify in body
///
[HttpPost]
- public async Task PostUser([FromBody] User inObj)
+ public async Task PostUser([FromBody] User inObj, ApiVersion apiVersion)
{
if (!serverState.IsOpen)
{
@@ -355,7 +356,7 @@ namespace AyaNova.Api.Controllers
//return success and link
//NOTE: this is a USER object so we don't want to return some key fields for security reasons
//which is why the object is "cleaned" before return
- return CreatedAtAction("GetUser", new { id = o.Id }, new ApiCreatedResponse(UserBiz.CleanUserForReturn(o)));
+ return CreatedAtAction(nameof(UserController.GetUser), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(UserBiz.CleanUserForReturn(o)));
}
}
diff --git a/server/AyaNova/Controllers/WidgetController.cs b/server/AyaNova/Controllers/WidgetController.cs
index 6f171957..87bd33de 100644
--- a/server/AyaNova/Controllers/WidgetController.cs
+++ b/server/AyaNova/Controllers/WidgetController.cs
@@ -265,6 +265,7 @@ namespace AyaNova.Api.Controllers
/// BizAdminFull, InventoryFull
///
///
+ /// Automatically filled from route path, no need to specify in body
///
[HttpPost]
public async Task PostWidget([FromBody] Widget inObj, ApiVersion apiVersion)
@@ -286,13 +287,9 @@ namespace AyaNova.Api.Controllers
Widget o = await biz.CreateAsync(inObj);
if (o == null)
return BadRequest(new ApiErrorResponse(biz.Errors));
- else
- {
- //originally but throwing exception since move to 3.1
- //return CreatedAtAction("GetWidget", new { id = o.Id }, new ApiCreatedResponse(o));
+ else
return CreatedAtAction(nameof(WidgetController.GetWidget), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
-
- }
+
}
@@ -302,10 +299,11 @@ namespace AyaNova.Api.Controllers
/// Required roles:
/// BizAdminFull, InventoryFull
///
- /// Create a duplicate of this item id
+ /// Create a duplicate of this items id
+ /// Automatically filled from route path, no need to specify in body
///
[HttpPost("duplicate/{id}")]
- public async Task DuplicateWidget([FromRoute] long id)
+ public async Task DuplicateWidget([FromRoute] long id, ApiVersion apiVersion)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
@@ -329,7 +327,7 @@ namespace AyaNova.Api.Controllers
if (o == null)
return BadRequest(new ApiErrorResponse(biz.Errors));
else
- return CreatedAtAction("GetWidget", new { id = o.Id }, new ApiCreatedResponse(o));
+ return CreatedAtAction(nameof(WidgetController.GetWidget), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
}
diff --git a/server/AyaNova/Startup.cs b/server/AyaNova/Startup.cs
index 8d655405..b16bca5a 100644
--- a/server/AyaNova/Startup.cs
+++ b/server/AyaNova/Startup.cs
@@ -174,8 +174,8 @@ namespace AyaNova
{
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".
- });
+ Scheme = "bearer" //The name of the HTTP Authorization scheme to be used in the Authorization header. In this case "bearer".
+ });
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
@@ -262,10 +262,13 @@ namespace AyaNova
{
_log.LogDebug("BOOT: configuring request pipeline...");
+ //this *may* be useful in the event of an issue so uncomment if necessary but errors during dev are handled equally by the logging, I think
// if (env.IsDevelopment())
// {
// app.UseDeveloperExceptionPage();
// }
+
+
//Store a reference to the dependency injection service for static classes
ServiceProviderProvider.Provider = app.ApplicationServices;
@@ -457,7 +460,7 @@ namespace AyaNova
static string XmlCommentsFilePath
{
get
- {
+ {
var basePath = AppContext.BaseDirectory;
var fileName = typeof(Startup).GetTypeInfo().Assembly.GetName().Name + ".xml";
return Path.Combine(basePath, fileName);