diff --git a/zero.Api/Abstractions/ZeroApiController.cs b/zero.Api/Abstractions/ZeroApiController.cs index 44ef10d3..36dea95a 100644 --- a/zero.Api/Abstractions/ZeroApiController.cs +++ b/zero.Api/Abstractions/ZeroApiController.cs @@ -5,9 +5,8 @@ namespace zero.Api.Abstractions; [ApiController] [ZeroAuthorize] -[DisableBrowserCacheFilter] -[ApiMetadataFilter] -[ApiResponseFilter] +//[ApiMetadataFilter] +//[ApiResponseFilter] //[ServiceFilter(typeof(ModelStateValidationFilterAttribute))] //[ServiceFilter(typeof(BackofficeFilterAttribute))] public abstract class ZeroApiController : ControllerBase diff --git a/zero.Api/Endpoints/Error/ErrorController.cs b/zero.Api/Endpoints/Error/ErrorController.cs index 5033c7ca..f13d54a5 100644 --- a/zero.Api/Endpoints/Error/ErrorController.cs +++ b/zero.Api/Endpoints/Error/ErrorController.cs @@ -8,17 +8,23 @@ public class ErrorController : ZeroApiController [HttpGet("")] public virtual ActionResult Index() { - IExceptionHandlerFeature exception = HttpContext.Features.Get(); - return new ErrorApiResponse() { Success = false, - Status = HttpContext.Response.StatusCode, - Error = new() - { - ApiPath = exception.Path, - Message = exception.Error.Message - } + Status = HttpContext.Response.StatusCode }; + + //IExceptionHandlerFeature exception = HttpContext.Features.Get(); + + //return new ErrorApiResponse() + //{ + // Success = false, + // Status = HttpContext.Response.StatusCode, + // Error = new() + // { + // ApiPath = exception.Path, + // Message = exception.Error.Message + // } + //}; } } \ No newline at end of file diff --git a/zero.Api/ZeroApiControllerModelConvention.cs b/zero.Api/ZeroApiControllerModelConvention.cs index 7b79209b..abcd3b3d 100644 --- a/zero.Api/ZeroApiControllerModelConvention.cs +++ b/zero.Api/ZeroApiControllerModelConvention.cs @@ -7,20 +7,24 @@ namespace zero.Api.Controllers; public class ZeroApiControllerModelConvention : IControllerModelConvention { + protected Type BaseClassType { get; set; } = typeof(ZeroApiController); + readonly AttributeRouteModel AppAwareRouteModel; readonly AttributeRouteModel AppUnawareRouteModel; - readonly Type BaseClass = typeof(ZeroApiController); + readonly Type SystemApiType = typeof(ZeroSystemApiAttribute); + + readonly ApiParameterTransformer Transformer = new(); readonly bool RuntimeIsAppAware = false; - public ZeroApiControllerModelConvention(string zeroPath, string apiPath = "api", bool isAppAware = false) + public ZeroApiControllerModelConvention(string path, bool isAppAware = false) { RuntimeIsAppAware = isAppAware; - AppAwareRouteModel = BuildRouteModel(zeroPath, apiPath, true); - AppUnawareRouteModel = BuildRouteModel(zeroPath, apiPath, false); + AppAwareRouteModel = BuildRouteModel(path, true); + AppUnawareRouteModel = BuildRouteModel(path, false); } @@ -31,20 +35,25 @@ public class ZeroApiControllerModelConvention : IControllerModelConvention { bool hasAttributeRouteModels = controller.Selectors.Any(selector => selector.AttributeRouteModel != null); - if (controller.ControllerType.IsSubclassOf(BaseClass)) + if (controller.ControllerType.IsSubclassOf(BaseClassType)) { - bool isAppAware = RuntimeIsAppAware && controller.ControllerType.GetCustomAttribute() == null; + bool isAppAware = RuntimeIsAppAware && controller.ControllerType.GetCustomAttribute(SystemApiType) == null; controller.Selectors[0].AttributeRouteModel = isAppAware ? AppAwareRouteModel : AppUnawareRouteModel; + controller.Filters.Add(new DisableBrowserCacheFilterAttribute()); + + foreach (var action in controller.Actions) + { + action.RouteParameterTransformer = Transformer; + } } } - protected AttributeRouteModel BuildRouteModel(string zeroPath, string apiPath, bool appAware = false) + protected AttributeRouteModel BuildRouteModel(string pathSegment, bool appAware = false) { StringBuilder path = new(); - path.Append(zeroPath.EnsureEndsWith('/')); - path.Append(apiPath.TrimStart('/').EnsureEndsWith('/')); + path.Append(pathSegment.EnsureSurroundedWith('/')); if (appAware) { diff --git a/zero.Api/ZeroApiMvcOptions.cs b/zero.Api/ZeroApiMvcOptions.cs index 59159420..d7afd377 100644 --- a/zero.Api/ZeroApiMvcOptions.cs +++ b/zero.Api/ZeroApiMvcOptions.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -18,7 +17,7 @@ internal class ZeroApiMvcOptions : IConfigureOptions public void Configure(MvcOptions options) { - options.Conventions.Add(new ZeroApiControllerModelConvention(Options.ZeroPath, isAppAware: Options.Applications.Count > 1)); - options.Conventions.Add(new RouteTokenTransformerConvention(new ApiParameterTransformer())); + Console.WriteLine("Configure API"); + options.Conventions.Add(new ZeroApiControllerModelConvention(Options.ZeroPath + "/api", isAppAware: Options.Applications.Count > 1)); } } \ No newline at end of file diff --git a/zero.Backoffice/Abstractions/ZeroBackofficeController.cs b/zero.Backoffice/Abstractions/ZeroBackofficeController.cs index 9c577422..a976e70b 100644 --- a/zero.Backoffice/Abstractions/ZeroBackofficeController.cs +++ b/zero.Backoffice/Abstractions/ZeroBackofficeController.cs @@ -1,12 +1,10 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; -using zero.Api.Controllers; namespace zero.Backoffice.Abstractions; [ApiController] [ZeroAuthorize] -[DisableBrowserCacheFilter] //[ServiceFilter(typeof(ModelStateValidationFilterAttribute))] //[ServiceFilter(typeof(BackofficeFilterAttribute))] public abstract class ZeroBackofficeController : ControllerBase diff --git a/zero.Backoffice/ZeroBackofficeControllerModelConvention.cs b/zero.Backoffice/ZeroBackofficeControllerModelConvention.cs index c0e06d6c..ea8f8658 100644 --- a/zero.Backoffice/ZeroBackofficeControllerModelConvention.cs +++ b/zero.Backoffice/ZeroBackofficeControllerModelConvention.cs @@ -1,41 +1,11 @@ -using Microsoft.AspNetCore.Mvc.ApplicationModels; -using System.Reflection; -using zero.Api.Controllers; -using zero.Api.Filters; +using zero.Api.Controllers; namespace zero.Backoffice; public class ZeroBackofficeControllerModelConvention : ZeroApiControllerModelConvention { - readonly AttributeRouteModel AppAwareRouteModel; - - readonly AttributeRouteModel AppUnawareRouteModel; - - readonly Type BaseClass = typeof(ZeroBackofficeController); - - readonly bool RuntimeIsAppAware = false; - - - public ZeroBackofficeControllerModelConvention(string zeroPath, string backofficeApiPath = "backoffice", bool isAppAware = false) : base(zeroPath, backofficeApiPath, isAppAware) + public ZeroBackofficeControllerModelConvention(string path, bool isAppAware = false) : base(path, isAppAware) { - RuntimeIsAppAware = isAppAware; - AppAwareRouteModel = BuildRouteModel(zeroPath, backofficeApiPath, true); - AppUnawareRouteModel = BuildRouteModel(zeroPath, backofficeApiPath, false); - } - - - /// - /// Configure routing model for all backoffice controllers - /// - public override void Apply(ControllerModel controller) - { - bool hasAttributeRouteModels = controller.Selectors.Any(selector => selector.AttributeRouteModel != null); - - if (controller.ControllerType.IsSubclassOf(BaseClass)) - { - bool isAppAware = RuntimeIsAppAware && controller.ControllerType.GetCustomAttribute() == null; - - controller.Selectors[0].AttributeRouteModel = isAppAware ? AppAwareRouteModel : AppUnawareRouteModel; - } + BaseClassType = typeof(ZeroBackofficeController); } } \ No newline at end of file diff --git a/zero.Backoffice/ZeroBackofficeMvcOptions.cs b/zero.Backoffice/ZeroBackofficeMvcOptions.cs index f620c628..c4a2f70a 100644 --- a/zero.Backoffice/ZeroBackofficeMvcOptions.cs +++ b/zero.Backoffice/ZeroBackofficeMvcOptions.cs @@ -15,6 +15,6 @@ internal class ZeroBackofficeMvcOptions : IConfigureOptions public void Configure(MvcOptions options) { - options.Conventions.Add(new ZeroBackofficeControllerModelConvention(Options.ZeroPath)); + options.Conventions.Add(new ZeroBackofficeControllerModelConvention(Options.ZeroPath + "/backoffice", Options.Applications.Count > 1)); } } \ No newline at end of file diff --git a/zero.Core/Routing/ZeroRoutesTransformer.cs b/zero.Core/Routing/ZeroRoutesTransformer.cs index eeefde4d..f0567c24 100644 --- a/zero.Core/Routing/ZeroRoutesTransformer.cs +++ b/zero.Core/Routing/ZeroRoutesTransformer.cs @@ -6,7 +6,7 @@ namespace zero.Routing; public class ZeroRoutesTransformer : DynamicRouteValueTransformer { - IRouteResolver RouteResolver; + readonly IRouteResolver RouteResolver; public ZeroRoutesTransformer(IRouteResolver routeResolver) { @@ -30,7 +30,7 @@ public class ZeroRoutesTransformer : DynamicRouteValueTransformer return null; } - httpContext.Features.Set(route); + httpContext.Features.Set(route); RouteEndpoint endpoint = RouteResolver.MapEndpoint(route); diff --git a/zero.Demo/Program.cs b/zero.Demo/Program.cs index c403a00b..cadd1cd6 100644 --- a/zero.Demo/Program.cs +++ b/zero.Demo/Program.cs @@ -39,12 +39,11 @@ if (!app.Environment.IsDevelopment()) app.UseZero().WithEndpoints(x => { //x.MapControllerRoute("default", "api/{controller}/{action=Index}/{id?}"); + x.MapControllers(); x.MapRazorPages(); x.MapZeroRoutes(); - //x.MapZeroBackoffice(); - x.MapFallbackToController("Index", "Error"); }); //app.UseZeroBackoffice(); -app.Run(); +app.Run(); \ No newline at end of file diff --git a/zero.Demo/SetupController.cs b/zero.Demo/SetupController.cs index 1875fadf..7e920abc 100644 --- a/zero.Demo/SetupController.cs +++ b/zero.Demo/SetupController.cs @@ -40,7 +40,7 @@ public class SetupController : Controller //} - [HttpGet] + [HttpGet("/api/setup/indexes")] public async Task Indexes([FromServices] IZeroStore store, [FromServices] IZeroContext context) { var indexes = context.Options.For().Indexes; @@ -57,7 +57,7 @@ public class SetupController : Controller } - [HttpGet] + [HttpGet("/api/setup/routes")] public async Task Routes([FromServices] IZeroStore store, [FromServices] IZeroContext context, [FromServices] IEnumerable providers) { RouteBulkRefresher refresher = new(store, context, providers); diff --git a/zero.Demo/appsettings.json b/zero.Demo/appsettings.json index 37a3db0e..b831d375 100644 --- a/zero.Demo/appsettings.json +++ b/zero.Demo/appsettings.json @@ -1,8 +1,17 @@ { "Zero": { - "Applications": { - "EnableMultiple": true - }, + "Applications": [ + { + "Key": "hofbauer", + "Name": "Hofbauer", + "Database": "laola.hofbauer" + }, + { + "Key": "brothers", + "Name": "brothers", + "Database": "laola.brothers" + } + ], "Raven": { "Url": "http://localhost:9800", "Database": "laola" @@ -16,4 +25,4 @@ } }, "AllowedHosts": "*" -} +} \ No newline at end of file