Update to latest packages and show examples
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
using GerstITS.Authentication.ApiKey;
|
||||
using GerstITS.System.Configurations;
|
||||
|
||||
namespace GerstITS.Examples.Api.Configurations;
|
||||
|
||||
internal class ApiKeyConfiguration : IApiKeyConfiguration
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public ApiKeyConfiguration(string parentPrefix,
|
||||
Microsoft.Extensions.Configuration.IConfiguration configuration)
|
||||
{
|
||||
var prefix = $"{parentPrefix}:{this.ToConfigurationPrefix()}";
|
||||
|
||||
Header = configuration.GetValue<string>($"{prefix}:{nameof(Header)}");
|
||||
Key = configuration.GetValue<string>($"{prefix}:{nameof(Key)}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IApiKeyConfiguration
|
||||
|
||||
public string Header { get; }
|
||||
public string Key { get; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Net;
|
||||
using GerstITS.Web.Api.ExceptionHandling;
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
|
||||
namespace GerstITS.Examples.Api.ExceptionHandling;
|
||||
|
||||
internal static class WebApplicationExtensions
|
||||
{
|
||||
internal static WebApplication UseGlobalExceptionHandling(this WebApplication app)
|
||||
{
|
||||
app.UseExceptionHandler(exceptionHandlerApp =>
|
||||
{
|
||||
exceptionHandlerApp.Run(async context =>
|
||||
{
|
||||
var exceptionFeature = context.Features.Get<IExceptionHandlerFeature>();
|
||||
if (exceptionFeature is null) return;
|
||||
|
||||
var exception = exceptionFeature.Error;
|
||||
var ticketId = Guid.NewGuid().ToString();
|
||||
|
||||
context.RequestServices
|
||||
.GetRequiredService<ILoggerFactory>()
|
||||
.CreateLogger("GlobalExceptionHandler")
|
||||
.LogError($"Global exception occurs (TicketId {ticketId}).{Environment.NewLine}{exception}");
|
||||
|
||||
var transformation = context.RequestServices
|
||||
.GetServices<IExceptionTransformation>()
|
||||
.FirstOrDefault(x => x.CanTransform(exception));
|
||||
|
||||
var info = transformation?.Transform(exception, ticketId) ?? new ExceptionTransformationInfo
|
||||
{
|
||||
StatusCode = HttpStatusCode.InternalServerError,
|
||||
ReasonPhrase = "Internal Server Error.",
|
||||
Details = $"An internal error occurs. Please contact support with ticket id '{ticketId}'."
|
||||
};
|
||||
|
||||
context.Response.StatusCode = (int)info.StatusCode;
|
||||
context.Features.Get<IHttpResponseFeature>().ReasonPhrase = info.ReasonPhrase;
|
||||
await context.Response.WriteAsync(info.Details ?? string.Empty);
|
||||
});
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
using Asp.Versioning;
|
||||
using GerstITS.Examples.Api.Versioning;
|
||||
using GerstITS.System.Caching;
|
||||
using GerstITS.Validation;
|
||||
using GerstITS.Web.Api;
|
||||
using GerstITS.Web.Api.FluentApi;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace GerstITS.Examples.Api.Controllers._1._1;
|
||||
|
||||
/// <summary>
|
||||
/// Is responsible to demonstrate the encrypted session based cache.
|
||||
/// </summary>
|
||||
[ApiController,
|
||||
ApiVersion(Versions._1_1),
|
||||
Route(ApplicationEnvironment.WebApi.ControllerRouteTemplate)]
|
||||
public class CacheController : FluentApiControllerBase
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private readonly ICache _cache;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public CacheController(ICache cache,
|
||||
IValidator validator)
|
||||
: base(validator)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a cached value by specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">Key of the cached value.</param>
|
||||
/// <returns>Returns the cached value.</returns>
|
||||
[HttpGet,
|
||||
Route("{key}")]
|
||||
public IActionResult Get(string key)
|
||||
{
|
||||
return Api().Use(key)
|
||||
.Get(_cache.Get<string>);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a value is cached for the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">Key of the cached value.</param>
|
||||
/// <returns>Returns true if a value is cached.</returns>
|
||||
[HttpGet,
|
||||
Route("{key}/Exists")]
|
||||
public IActionResult Exists(string key)
|
||||
{
|
||||
return Api().Use(key)
|
||||
.Get(_cache.ContainsKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caches a value for the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">Key of the value to cache.</param>
|
||||
/// <param name="value">Value to cache.</param>
|
||||
/// <returns>Returns the cached value.</returns>
|
||||
[HttpPost,
|
||||
Route("{key}")]
|
||||
public IActionResult Set(string key, [FromBody] string value)
|
||||
{
|
||||
return Api().Use(key)
|
||||
.Create(x => {
|
||||
_cache.Set(x, value);
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a cached value by specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">Key of the cached value.</param>
|
||||
/// <returns>Returns true if the value was removed.</returns>
|
||||
[HttpDelete,
|
||||
Route("{key}")]
|
||||
public IActionResult Remove(string key)
|
||||
{
|
||||
return Api().Use(key)
|
||||
.Delete(x => {
|
||||
_cache.Remove(x);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Asp.Versioning;
|
||||
using GerstITS.Examples.Api.Versioning;
|
||||
using GerstITS.Mail;
|
||||
using GerstITS.Validation;
|
||||
using GerstITS.Web.Api;
|
||||
using GerstITS.Web.Api.FluentApi;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace GerstITS.Examples.Api.Controllers._1._1;
|
||||
|
||||
/// <summary>
|
||||
/// Is responsible to send contact requests via the configured smtp mail provider.
|
||||
/// </summary>
|
||||
[ApiController,
|
||||
ApiVersion(Versions._1_1),
|
||||
Route(ApplicationEnvironment.WebApi.ControllerRouteTemplate)]
|
||||
public class ContactController : FluentApiControllerBase
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private const string _supportAddress = "support@example.com";
|
||||
|
||||
private readonly IMailProvider _mailProvider;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public ContactController(IMailProvider mailProvider,
|
||||
IValidator validator)
|
||||
: base(validator)
|
||||
{
|
||||
_mailProvider = mailProvider;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Sends a contact request as mail to the support address.
|
||||
/// </summary>
|
||||
/// <param name="contactRequest">Contact request to send.</param>
|
||||
/// <returns>Returns true if the mail was sent.</returns>
|
||||
[HttpPost]
|
||||
public IActionResult Send([FromBody] ContactRequest contactRequest)
|
||||
{
|
||||
return Api().Use(contactRequest)
|
||||
.Create(x => _mailProvider.SendMail(ToMailNotification(x)));
|
||||
}
|
||||
|
||||
private static MailNotification ToMailNotification(ContactRequest contactRequest)
|
||||
{
|
||||
return new MailNotification
|
||||
{
|
||||
Recipients = new[] { _supportAddress },
|
||||
Subject = $"{contactRequest.Subject} ({contactRequest.SenderName}, {contactRequest.SenderEmail})",
|
||||
Body = contactRequest.Body,
|
||||
IsHtmlMail = false
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
using Asp.Versioning;
|
||||
using GerstITS.Data;
|
||||
using GerstITS.Examples.Api.Versioning;
|
||||
using GerstITS.Examples.Logic.Customers;
|
||||
using GerstITS.Search;
|
||||
using GerstITS.Validation;
|
||||
using GerstITS.Web.Api;
|
||||
using GerstITS.Web.Api.FluentApi;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace GerstITS.Examples.Api.Controllers._1._1;
|
||||
|
||||
/// <summary>
|
||||
/// Is responsible to manage customers backed by the repository based data access.
|
||||
/// </summary>
|
||||
[ApiController,
|
||||
ApiVersion(Versions._1_1),
|
||||
Route(ApplicationEnvironment.WebApi.ControllerRouteTemplate)]
|
||||
public class CustomerController : FluentApiControllerBase
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private readonly ICustomerProvider _provider;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public CustomerController(ICustomerProvider provider,
|
||||
IValidator validator)
|
||||
: base(validator)
|
||||
{
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a customer by specified id. Deactivated customers are excluded by default.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the customer.</param>
|
||||
/// <param name="includeInactive">Includes deactivated (soft deleted) customers if set to true.</param>
|
||||
/// <returns>Returns a customer.</returns>
|
||||
[HttpGet,
|
||||
Route("{id}")]
|
||||
public IActionResult Get(int id, [FromQuery] bool includeInactive = false)
|
||||
{
|
||||
return Api().Use(id)
|
||||
.Get(x => _provider.GetById(x, includeInactive));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches customers by specified filter using the search engine (paging, sorting, filtering).
|
||||
/// </summary>
|
||||
/// <param name="filter">Filter criteria of the search.</param>
|
||||
/// <returns>Returns the matching customers including the total count.</returns>
|
||||
[HttpPost,
|
||||
Route("Search")]
|
||||
public IActionResult Search([FromBody] CustomerSearchFilter filter)
|
||||
{
|
||||
return Api().Use(filter)
|
||||
.Get(_provider.Search);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new customer.
|
||||
/// </summary>
|
||||
/// <param name="customer">Customer to create.</param>
|
||||
/// <returns>Returns the created customer.</returns>
|
||||
[HttpPost]
|
||||
public IActionResult Create([FromBody] Customer customer)
|
||||
{
|
||||
return Api().Use(customer)
|
||||
.Create(_provider.Create);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates an existing customer.
|
||||
/// </summary>
|
||||
/// <param name="customer">Customer to update.</param>
|
||||
/// <returns>Returns the updated customer.</returns>
|
||||
[HttpPut]
|
||||
public IActionResult Update([FromBody] Customer customer)
|
||||
{
|
||||
return Api().Use(customer)
|
||||
.Update(_provider.Update);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a customer. Performs a soft delete by default, a permanent delete if force is set to true.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the customer.</param>
|
||||
/// <param name="force">Deletes the customer permanently if set to true.</param>
|
||||
/// <returns>Returns true if the customer was deleted.</returns>
|
||||
[HttpDelete,
|
||||
Route("{id}")]
|
||||
public IActionResult Delete(int id, [FromQuery] bool force = false)
|
||||
{
|
||||
return Api().Use(id)
|
||||
.Delete(x => _provider.Delete(x, force));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports customers using bulk operations.
|
||||
/// </summary>
|
||||
/// <param name="customers">Customers to import.</param>
|
||||
/// <returns>Returns the bulk operation result.</returns>
|
||||
[HttpPost,
|
||||
Route("Import")]
|
||||
public IActionResult Import([FromBody] IEnumerable<Customer> customers)
|
||||
{
|
||||
return Api().Use(customers)
|
||||
.Create(_provider.Import);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all notes of a customer ordered by their validity.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the customer.</param>
|
||||
/// <returns>Returns the notes of the customer.</returns>
|
||||
[HttpGet,
|
||||
Route("{id}/Notes")]
|
||||
public IActionResult GetNotes(int id)
|
||||
{
|
||||
return Api().Use(id)
|
||||
.Get(_provider.GetNotes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a historicized note to a customer.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the customer.</param>
|
||||
/// <param name="note">Note to add.</param>
|
||||
/// <returns>Returns the created note.</returns>
|
||||
[HttpPost,
|
||||
Route("{id}/Notes")]
|
||||
public IActionResult AddNote(int id, [FromBody] CustomerNote note)
|
||||
{
|
||||
return Api().Use(id)
|
||||
.Create(x => _provider.AddNote(x, note.Text));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using Asp.Versioning;
|
||||
using GerstITS.Authentication.ApiKey;
|
||||
using GerstITS.Examples.Api.Versioning;
|
||||
using GerstITS.System.Environment;
|
||||
using GerstITS.Validation;
|
||||
using GerstITS.Web.Api;
|
||||
using GerstITS.Web.Api.FluentApi;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace GerstITS.Examples.Api.Controllers._1._1;
|
||||
|
||||
/// <summary>
|
||||
/// Is responsible to provide maintenance functions protected by an api key header.
|
||||
/// </summary>
|
||||
[ApiController,
|
||||
ApiVersion(Versions._1_1),
|
||||
ApiKey,
|
||||
Route(ApplicationEnvironment.WebApi.ControllerRouteTemplate)]
|
||||
public class MaintenanceController : FluentApiControllerBase
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private readonly ISystemClock _systemClock;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public MaintenanceController(ISystemClock systemClock,
|
||||
IValidator validator)
|
||||
: base(validator)
|
||||
{
|
||||
_systemClock = systemClock;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current server time. Requires a valid api key header.
|
||||
/// </summary>
|
||||
/// <returns>Returns the current server time.</returns>
|
||||
[HttpGet,
|
||||
Route("Ping")]
|
||||
public IActionResult Ping()
|
||||
{
|
||||
return Api().Get(() => _systemClock.UtcNow);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Asp.Versioning;
|
||||
using GerstITS.Examples.Api.Versioning;
|
||||
using GerstITS.Validation;
|
||||
using GerstITS.Web.Api;
|
||||
using GerstITS.Web.Api.FluentApi;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace GerstITS.Examples.Api.Controllers._1._1;
|
||||
|
||||
/// <summary>
|
||||
/// Is responsible to demonstrate open id (jwt bearer) protected endpoints.
|
||||
/// </summary>
|
||||
[ApiController,
|
||||
ApiVersion(Versions._1_1),
|
||||
Authorize,
|
||||
Route(ApplicationEnvironment.WebApi.ControllerRouteTemplate)]
|
||||
public class SecuredController : FluentApiControllerBase
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public SecuredController(IValidator validator)
|
||||
: base(validator)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the authenticated user. Requires a valid bearer token.
|
||||
/// </summary>
|
||||
/// <returns>Returns the name of the authenticated user.</returns>
|
||||
[HttpGet,
|
||||
Route("Me")]
|
||||
public IActionResult Me()
|
||||
{
|
||||
return Api().Get(() => User.Identity.Name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using GerstITS.Examples.Logic.Customers;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace GerstITS.Examples.Api.Endpoints;
|
||||
|
||||
internal static partial class Endpoints
|
||||
{
|
||||
internal static RouteGroupBuilder MapCustomerNoteEndpoints(this RouteGroupBuilder group)
|
||||
{
|
||||
CustomerNotes.MapGetByCustomer(group);
|
||||
CustomerNotes.MapAdd(group);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
internal static class CustomerNotes
|
||||
{
|
||||
internal static void MapGetByCustomer(RouteGroupBuilder group)
|
||||
{
|
||||
group.MapGet("customers/{id:int}/notes", (int id, ICustomerProvider customerProvider) =>
|
||||
Results.Ok(customerProvider.GetNotes(id)));
|
||||
}
|
||||
|
||||
internal static void MapAdd(RouteGroupBuilder group)
|
||||
{
|
||||
group.MapPost("customers/{id:int}/notes", (int id, [FromBody] CustomerNote note, ICustomerProvider customerProvider) =>
|
||||
Results.Ok(customerProvider.AddNote(id, note.Text)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using GerstITS.Examples.Logic.Customers;
|
||||
using GerstITS.Validation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace GerstITS.Examples.Api.Endpoints;
|
||||
|
||||
internal static partial class Endpoints
|
||||
{
|
||||
internal static RouteGroupBuilder MapCustomerEndpoints(this IEndpointRouteBuilder root)
|
||||
{
|
||||
var group = root.MapGroup("/api/v2.0")
|
||||
.WithTags("Customers");
|
||||
|
||||
Customers.MapGetById(group);
|
||||
Customers.MapSearch(group);
|
||||
Customers.MapCreate(group);
|
||||
Customers.MapUpdate(group);
|
||||
Customers.MapDelete(group);
|
||||
Customers.MapImport(group);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
internal static class Customers
|
||||
{
|
||||
internal static void MapGetById(RouteGroupBuilder group)
|
||||
{
|
||||
group.MapGet("customers/{id:int}", (int id, ICustomerProvider customerProvider, bool includeInactive = false) =>
|
||||
Results.Ok(customerProvider.GetById(id, includeInactive)));
|
||||
}
|
||||
|
||||
internal static void MapSearch(RouteGroupBuilder group)
|
||||
{
|
||||
group.MapGet("customers", ([AsParameters] CustomerSearchFilter filter, ICustomerProvider customerProvider, IValidator validator) =>
|
||||
{
|
||||
Validator.Validate(validator, filter);
|
||||
|
||||
return Results.Ok(customerProvider.Search(filter));
|
||||
});
|
||||
}
|
||||
|
||||
internal static void MapCreate(RouteGroupBuilder group)
|
||||
{
|
||||
group.MapPost("customers", ([FromBody] Customer customer, ICustomerProvider customerProvider, IValidator validator) =>
|
||||
{
|
||||
Validator.Validate(validator, customer);
|
||||
|
||||
return Results.Ok(customerProvider.Create(customer));
|
||||
});
|
||||
}
|
||||
|
||||
internal static void MapUpdate(RouteGroupBuilder group)
|
||||
{
|
||||
group.MapPut("customers/{id:int}", (int id, [FromBody] Customer customer, ICustomerProvider customerProvider, IValidator validator) =>
|
||||
{
|
||||
customer.Id = id;
|
||||
Validator.Validate(validator, customer);
|
||||
|
||||
return Results.Ok(customerProvider.Update(customer));
|
||||
});
|
||||
}
|
||||
|
||||
internal static void MapDelete(RouteGroupBuilder group)
|
||||
{
|
||||
group.MapDelete("customers/{id:int}", (int id, ICustomerProvider customerProvider, bool force = false) =>
|
||||
Results.Ok(customerProvider.Delete(id, force)));
|
||||
}
|
||||
|
||||
internal static void MapImport(RouteGroupBuilder group)
|
||||
{
|
||||
group.MapPost("customers/import", ([FromBody] IEnumerable<Customer> customers, ICustomerProvider customerProvider) =>
|
||||
Results.Ok(customerProvider.Import(customers)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using GerstITS.Validation;
|
||||
|
||||
namespace GerstITS.Examples.Api.Endpoints;
|
||||
|
||||
internal static partial class Endpoints
|
||||
{
|
||||
internal static class Validator
|
||||
{
|
||||
internal static void Validate<T>(IValidator validator, T model)
|
||||
{
|
||||
var result = validator.Validate(model);
|
||||
|
||||
if (!result.IsValid)
|
||||
throw new ValidationException($"{typeof(T).Name} is invalid.{Environment.NewLine}Details: {result.ToErrorMessage()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace GerstITS.Examples.Api.Endpoints;
|
||||
|
||||
internal static partial class Endpoints
|
||||
{
|
||||
internal static RouteGroupBuilder MapEndpoints(this IEndpointRouteBuilder root)
|
||||
{
|
||||
return root.MapCustomerEndpoints()
|
||||
.MapCustomerNoteEndpoints();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using GerstITS.Web.Http;
|
||||
|
||||
namespace GerstITS.Examples.Api;
|
||||
|
||||
public sealed partial class Module
|
||||
{
|
||||
#region Methods
|
||||
|
||||
private static void RegisterSession(IServiceCollection container)
|
||||
{
|
||||
container.AddDistributedMemoryCache();
|
||||
container.AddHttpSession();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using GerstITS.Examples.Api.Endpoints;
|
||||
using GerstITS.Examples.Api.ExceptionHandling;
|
||||
using GerstITS.Web.Api;
|
||||
using GerstITS.Web.Api.Hosting;
|
||||
using GerstITS.Web.Api.Swagger;
|
||||
@@ -23,6 +25,7 @@ public class Program
|
||||
.Services()
|
||||
.Build()
|
||||
.IfProduction(app => app.UsePreconfiguredHsts())
|
||||
.UseGlobalExceptionHandling()
|
||||
.IfDevelopment(app => app.UseDeveloperExceptionPage()
|
||||
.UsePreconfiguredSwagger())
|
||||
.UsePreconfiguredCors()
|
||||
@@ -32,7 +35,11 @@ public class Program
|
||||
.UseAuthorization()
|
||||
.UseRouting()
|
||||
.UseSession()
|
||||
.UseEndpoints(endpoints => endpoints.MapControllers())
|
||||
.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapEndpoints();
|
||||
})
|
||||
.UseRewriteUnknownPathsToIndexSite(ApplicationEnvironment.WebApi.BaseUrl)
|
||||
.UseSystemIndependentStaticFiles()
|
||||
.UseSerilogRequestLogging()
|
||||
|
||||
Reference in New Issue
Block a user