diff --git a/zero.Core/Routing/PageRouteProvider/PageRouteProvider.cs b/zero.Core/Routing/PageRouteProvider/PageRouteProvider.cs index 353b5613..3366a711 100644 --- a/zero.Core/Routing/PageRouteProvider/PageRouteProvider.cs +++ b/zero.Core/Routing/PageRouteProvider/PageRouteProvider.cs @@ -96,8 +96,12 @@ public class PageRouteProvider : ZeroRouteProvider /// /// Get parents for a page /// - protected virtual async Task> GetParents(RoutingContext context, Page model) + protected virtual async Task> GetParents(RoutingContext context, Page model) { + if (model == null) + { + return new(); + } zero_Pages_ByHierarchy.Result result = await context.Session.Query() .ProjectInto() .Include(x => x.Path.Select(p => p.Id)) @@ -105,7 +109,7 @@ public class PageRouteProvider : ZeroRouteProvider if (result == null) { - return new List(); + return new(); } return (await context.Session.LoadAsync(result.Path.Select(x => x.Id))).Select(x => x.Value).ToList(); diff --git a/zero.Core/Routing/Routes.cs b/zero.Core/Routing/Routes.cs index 7cafd2c2..9b332873 100644 --- a/zero.Core/Routing/Routes.cs +++ b/zero.Core/Routing/Routes.cs @@ -94,6 +94,15 @@ public class Routes : IRoutes } + /// + public virtual bool TryGetProvider(T model, bool forSeeding, out IRouteProvider provider) where T : ISupportsRouting + { + Type type = model.GetType(); + provider = Providers.OrderByDescending(x => x.Priority).FirstOrDefault(x => x.CanHandle(type) && (!forSeeding || x.CanSeed(type))); + return provider != null; + } + + /// public virtual bool TryGetProvider(string alias, out IRouteProvider provider) { @@ -178,6 +187,11 @@ public interface IRoutes /// bool TryGetProvider(T model, out IRouteProvider provider) where T : ISupportsRouting; + /// + /// Find a provider for a certain entity + /// + bool TryGetProvider(T model, bool forSeeding, out IRouteProvider provider) where T : ISupportsRouting; + /// /// Find a provider by alias /// diff --git a/zero.Core/Routing/ZeroEntityRouteInterceptor.cs b/zero.Core/Routing/ZeroEntityRouteInterceptor.cs index 8b4cebcf..01d431cb 100644 --- a/zero.Core/Routing/ZeroEntityRouteInterceptor.cs +++ b/zero.Core/Routing/ZeroEntityRouteInterceptor.cs @@ -118,7 +118,7 @@ public class ZeroEntityRouteInterceptor : Interceptor // find provider for this model - if (Routes.TryGetProvider(model, out IRouteProvider provider)) + if (Routes.TryGetProvider(model, true, out IRouteProvider provider)) { // return if the route is not stale if (args.PreviousModel is ZeroEntity previousZeroModel && !(await provider.IsRouteStale(context, previousZeroModel, model))) diff --git a/zero.Core/Routing/ZeroRouteProvider.cs b/zero.Core/Routing/ZeroRouteProvider.cs index fdb5e600..c9ae3c89 100644 --- a/zero.Core/Routing/ZeroRouteProvider.cs +++ b/zero.Core/Routing/ZeroRouteProvider.cs @@ -7,6 +7,9 @@ public abstract class ZeroRouteProvider : ZeroRouteProvider, IRouteProvider public override bool CanHandle(Type type) => typeof(T).IsAssignableFrom(type); + /// + public override bool CanSeed(Type type) => CanHandle(type); + /// public virtual Task Create(RoutingContext context, T model) => base.Create(context, model); @@ -80,6 +83,9 @@ public abstract class ZeroRouteProvider : IRouteProvider /// public virtual bool CanHandle(Type type) => false; + /// + public virtual bool CanSeed(Type type) => false; + /// public virtual Task Create(RoutingContext context, ISupportsRouting model) => Task.FromResult(new Route() { @@ -193,6 +199,11 @@ public interface IRouteProvider /// bool CanHandle(Type type); + /// + /// Whether this provider can handle seeding for a certain entity type + /// + bool CanSeed(Type type); + /// /// Generate unique route key for a model ///