diff --git a/src/cloudscribe.Web.Navigation/CachingNavigationViewComponent.cs b/src/cloudscribe.Web.Navigation/CachingNavigationViewComponent.cs index 38bade6..82f2cd1 100644 --- a/src/cloudscribe.Web.Navigation/CachingNavigationViewComponent.cs +++ b/src/cloudscribe.Web.Navigation/CachingNavigationViewComponent.cs @@ -64,12 +64,17 @@ public CachingNavigationViewComponent( // In a simplecontent system I'd probably need to use the IHandlePageCreated (etc) // hooks to clear a navcache of known name. - public async Task InvokeAsync(string viewName, - string filterName, - string startingNodeKey, + public async Task InvokeAsync(string viewName, + string filterName, + string startingNodeKey, int expirationSeconds = 60, bool testMode = false) { + if (NavigationSuppressor.IsFilterSuppressed(Request.HttpContext, filterName)) + { + return Content(string.Empty); + } + NavigationViewModel model = null; string cacheKey = $"{viewName}_{filterName}_{startingNodeKey}"; diff --git a/src/cloudscribe.Web.Navigation/Constants.cs b/src/cloudscribe.Web.Navigation/Constants.cs index 0267359..1e91799 100644 --- a/src/cloudscribe.Web.Navigation/Constants.cs +++ b/src/cloudscribe.Web.Navigation/Constants.cs @@ -9,5 +9,6 @@ namespace cloudscribe.Web.Navigation public static class Constants { public static readonly string TailCrumbsContexctKey = "navigationtailcrumbs"; + public static readonly string NavigationSuppressContextKey = "navigation-suppress"; } } diff --git a/src/cloudscribe.Web.Navigation/NavigationSuppressor.cs b/src/cloudscribe.Web.Navigation/NavigationSuppressor.cs new file mode 100644 index 0000000..9bf7aa4 --- /dev/null +++ b/src/cloudscribe.Web.Navigation/NavigationSuppressor.cs @@ -0,0 +1,43 @@ +// Copyright (c) Source Tree Solutions, LLC. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; + +namespace cloudscribe.Web.Navigation +{ + /// + /// Allows consuming applications to suppress specific navigation filters for the current request. + /// When a filter is suppressed, the NavigationViewComponent and CachingNavigationViewComponent + /// will return empty content immediately, avoiding all tree-building computation. + /// + public static class NavigationSuppressor + { + public static void SuppressFilter(HttpContext context, string filterName) + { + if (context == null) throw new ArgumentNullException(nameof(context)); + if (string.IsNullOrEmpty(filterName)) return; + + var key = Constants.NavigationSuppressContextKey; + if (context.Items[key] is not HashSet suppressed) + { + suppressed = new HashSet(StringComparer.OrdinalIgnoreCase); + context.Items[key] = suppressed; + } + suppressed.Add(filterName); + } + + public static bool IsFilterSuppressed(HttpContext context, string filterName) + { + if (context == null) return false; + if (string.IsNullOrEmpty(filterName)) return false; + + if (context.Items[Constants.NavigationSuppressContextKey] is HashSet suppressed) + { + return suppressed.Contains(filterName); + } + return false; + } + } +} diff --git a/src/cloudscribe.Web.Navigation/NavigationViewComponent.cs b/src/cloudscribe.Web.Navigation/NavigationViewComponent.cs index 399359f..5448ef2 100644 --- a/src/cloudscribe.Web.Navigation/NavigationViewComponent.cs +++ b/src/cloudscribe.Web.Navigation/NavigationViewComponent.cs @@ -47,6 +47,11 @@ public NavigationViewComponent( public async Task InvokeAsync(string viewName, string filterName, string startingNodeKey) { + if (NavigationSuppressor.IsFilterSuppressed(Request.HttpContext, filterName)) + { + return Content(string.Empty); + } + var rootNode = await _builder.GetTree(); var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccesor.ActionContext); NavigationViewModel model = new NavigationViewModel(