diff --git a/zero.Api/Plugin.cs b/zero.Api/Plugin.cs index 1704916b..283c2a35 100644 --- a/zero.Api/Plugin.cs +++ b/zero.Api/Plugin.cs @@ -22,8 +22,7 @@ public class ZeroApiPlugin : ZeroPlugin public override void ConfigureServices(IServiceCollection services, IConfiguration configuration) { services.AddOptions().Bind(configuration.GetSection("Zero:Api")).Configure(ConfigureOptions); - services.TryAddEnumerable(ServiceDescriptor.Transient, ZeroBackofficeMvcOptions>()); - + services.TryAddEnumerable(ServiceDescriptor.Transient, ZeroApiMvcOptions>()); //Mvc.AddNewtonsoftJson(x => //{ // // TODO this shall only be configurated for backoffice controllers @@ -34,11 +33,6 @@ public class ZeroApiPlugin : ZeroPlugin services.AddZeroBackofficeModules(configuration); - services.AddControllers(opts => - { - opts.Conventions.Add(new RouteTokenTransformerConvention(new ApiParameterTransformer())); - }); - //services.AddTransient(); //services.AddTransient(); diff --git a/zero.Api/ZeroApiControllerModelConvention.cs b/zero.Api/ZeroApiControllerModelConvention.cs new file mode 100644 index 00000000..8c917355 --- /dev/null +++ b/zero.Api/ZeroApiControllerModelConvention.cs @@ -0,0 +1,43 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ApplicationModels; +using System.Text; + +namespace zero.Api.Controllers; + +public class ZeroApiControllerModelConvention : IControllerModelConvention +{ + readonly AttributeRouteModel RouteModel; + + readonly Type BaseClass = typeof(ZeroApiController); + + + public ZeroApiControllerModelConvention(string zeroPath, string apiPath = "api", bool isAppAware = false) + { + StringBuilder path = new(); + path.Append(zeroPath.EnsureEndsWith('/')); + path.Append(apiPath.TrimStart('/').EnsureEndsWith('/')); + + if (isAppAware) + { + path.Append("{zero_app_slug}/"); + } + + path.Append("[controller]"); + + RouteModel = new AttributeRouteModel(new RouteAttribute(path.ToString())); + } + + + /// + /// Configure routing model for all backoffice controllers + /// + public void Apply(ControllerModel controller) + { + bool hasAttributeRouteModels = controller.Selectors.Any(selector => selector.AttributeRouteModel != null); + + if (controller.ControllerType.IsSubclassOf(BaseClass)) + { + controller.Selectors[0].AttributeRouteModel = RouteModel; + } + } +} \ No newline at end of file diff --git a/zero.Api/ZeroApiMvcOptions.cs b/zero.Api/ZeroApiMvcOptions.cs new file mode 100644 index 00000000..14c57810 --- /dev/null +++ b/zero.Api/ZeroApiMvcOptions.cs @@ -0,0 +1,24 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ApplicationModels; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; + +namespace zero.Api; + +internal class ZeroApiMvcOptions : IConfigureOptions +{ + IZeroOptions Options { get; set; } + + public ZeroApiMvcOptions(IZeroOptions options) + { + Options = options; + } + + public void Configure(MvcOptions options) + { + options.Conventions.Add(new ZeroApiControllerModelConvention(Options.ZeroPath, isAppAware: Options.For().EnableMultiple)); + options.Conventions.Add(new RouteTokenTransformerConvention(new ApiParameterTransformer())); + } +} \ No newline at end of file diff --git a/zero.Api/ZeroBackofficeMvcOptions.cs b/zero.Api/ZeroBackofficeMvcOptions.cs deleted file mode 100644 index e645f6ac..00000000 --- a/zero.Api/ZeroBackofficeMvcOptions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ApplicationModels; -using Microsoft.Extensions.Options; -using zero.Api.Filters; - -namespace zero.Api; - -internal class ZeroBackofficeMvcOptions : IConfigureOptions -{ - IZeroOptions Options { get; set; } - - public ZeroBackofficeMvcOptions(IZeroOptions options) - { - Options = options; - } - - public void Configure(MvcOptions options) - { - options.Conventions.Add(new ZeroBackofficeControllerModelConvention(Options.ZeroPath)); - //options.Conventions.Add(new RouteTokenTransformerConvention(new ApiParameterTransformer())); - } -} \ No newline at end of file diff --git a/zero.Backoffice/Controllers/ZeroBackofficeController.cs b/zero.Backoffice/Controllers/ZeroBackofficeController.cs new file mode 100644 index 00000000..e63759e0 --- /dev/null +++ b/zero.Backoffice/Controllers/ZeroBackofficeController.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using zero.Api.Controllers; + +namespace zero.Backoffice.Controllers; + +[ApiController] +[ZeroAuthorize] +[DisableBrowserCache] +//[ServiceFilter(typeof(ModelStateValidationFilterAttribute))] +//[ServiceFilter(typeof(BackofficeFilterAttribute))] +public abstract class ZeroBackofficeController : ControllerBase +{ + IZeroMapper _mapper; + protected IZeroMapper Mapper => _mapper ?? (_mapper = HttpContext?.RequestServices?.GetService()); +} diff --git a/zero.Api/ZeroBackofficeControllerModelConvention.cs b/zero.Backoffice/ZeroBackofficeControllerModelConvention.cs similarity index 90% rename from zero.Api/ZeroBackofficeControllerModelConvention.cs rename to zero.Backoffice/ZeroBackofficeControllerModelConvention.cs index 08d118c5..0e36ff3b 100644 --- a/zero.Api/ZeroBackofficeControllerModelConvention.cs +++ b/zero.Backoffice/ZeroBackofficeControllerModelConvention.cs @@ -1,13 +1,13 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationModels; -namespace zero.Api.Controllers; +namespace zero.Backoffice; public class ZeroBackofficeControllerModelConvention : IApplicationModelConvention { readonly AttributeRouteModel RouteModel; - readonly Type BaseClass = typeof(ZeroApiController); + readonly Type BaseClass = typeof(ZeroBackofficeController); public ZeroBackofficeControllerModelConvention(string backofficePath) diff --git a/zero.Backoffice/ZeroBackofficeMvcOptions.cs b/zero.Backoffice/ZeroBackofficeMvcOptions.cs index ab7a37d5..a720074e 100644 --- a/zero.Backoffice/ZeroBackofficeMvcOptions.cs +++ b/zero.Backoffice/ZeroBackofficeMvcOptions.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; -using zero.Api.Controllers; namespace zero.Backoffice; diff --git a/zero.Core/ZeroApplicationBuilder.cs b/zero.Core/ZeroApplicationBuilder.cs index cbe5fdc9..67b4b8ed 100644 --- a/zero.Core/ZeroApplicationBuilder.cs +++ b/zero.Core/ZeroApplicationBuilder.cs @@ -14,8 +14,8 @@ public class ZeroApplicationBuilder : IZeroApplicationBuilder App = app; App.UseStaticFiles(); App.UseExceptionHandler("/zero/api/error"); - App.UseMiddleware(); App.UseRouting(); + App.UseMiddleware(); App.UseAuthentication(); App.UseAuthorization();