Comments (10)
@jimmyca15 IMO, this would really increase the value of this library and shouldn't be difficult to implement.
We already implemented a a very simple IAsyncPageFilter with similar implementation provided by @haacked and it's nicely working:
[AttributeUsage(AttributeTargets.Class)]
public class RazorPageFeatureGate : Attribute, IAsyncPageFilter
{
private string Feature { get; }
public RazorPageFeatureGate(string feature)
=> Feature = feature;
public virtual async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
{
var fm = context.HttpContext.RequestServices.GetRequiredService<IFeatureManagerSnapshot>();
var isEnabled = await fm.IsEnabledAsync(Feature).ConfigureAwait(false);
if (isEnabled)
{
await next.Invoke().ConfigureAwait(false);
}
else
{
context.HttpContext.Response.StatusCode = 404;
await context.HttpContext.Response.CompleteAsync().ConfigureAwait(false);
}
}
public virtual Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) => Task.CompletedTask;
}
from featuremanagement-dotnet.
Just as a follow-up, I hacked up a proof of concept to show this would work.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class FeatureToggleAttribute : FeatureGateAttribute
{
public FeatureToggleAttribute(params string[] features)
: this(RequirementType.All, features)
{
}
public FeatureToggleAttribute(RequirementType requirementType, params string[] features)
: base(requirementType, features)
{
}
public FeatureToggleAttribute(RequirementType requirementType, params object[] features)
: base(requirementType, features)
{
}
public FeatureToggleAttribute(params object[] features)
: this(RequirementType.All, features)
{
}
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
var fm = context.HttpContext.RequestServices.GetRequiredService<IFeatureManagerSnapshot>();
bool flag;
if (RequirementType == RequirementType.All)
flag = await Features.All<string>((Func<string, Task<bool>>) (async feature =>
await fm.IsEnabledAsync(feature).ConfigureAwait(false)));
else
flag = await Features.Any<string>((Func<string, Task<bool>>) (async feature =>
await fm.IsEnabledAsync(feature).ConfigureAwait(false)));
if (flag)
{
await next().ConfigureAwait(false);
}
else
{
context.HttpContext.Response.StatusCode = 404;
await context.HttpContext.Response.CompleteAsync();
}
}
}
This code makes use of internal classes within this repo that I didn't copy. But it shows that the basic idea would work.
from featuremanagement-dotnet.
This has been released in Microsoft.FeatureManagement.AspNetCore 2.5.0
Documentation update is in the works.
from featuremanagement-dotnet.
Calling Complete
on the response also disables custom error pages.
context.HttpContext.Response.StatusCode = 404;
await context.HttpContext.Response.CompleteAsync().ConfigureAwait(false);
Wouldn't it be better to avoid page execution by setting the PageHandlerExecutingContext.Result
?
context.Result = new NotFoundResult();
from featuremanagement-dotnet.
+1 for this as this is exactly what we were looking at as a solution in one of our apps ..
from featuremanagement-dotnet.
I spent some time looking into this because I wanted to provide some out of the box support for Razor Pages in the same way that we provide it for MVC controllers. There is an unfortunate difference between supporting controllers via OnActionExecutionAsync
and support Razor Pages via OnResultExecutionAsync
. OnResultExecutionAsync
is invoked after a page handler has already executed. You are correct that this is the only way to declaratively add a handler to a Page Handler. If we wanted to support Razor Pages with just an attribute, we would have to take that route, but the intent of the FeatureGate
attribute is to prevent the action/handler from running if the feature is not enabled. Therefore, it looks like support for this may not be a good option with what is available directly out of ASP.NET Core.
I will look a bit more to see if it makes sense to provide a global IPageFilter
that can check if a page is decorated with a FeatureGateAttribute
and execute it before the handler similar to how it works in an MVC scenario. This may require expensive reflection though and additional boiler plate code on startup to add the global filter.
from featuremanagement-dotnet.
Good point on the result execution filter being too late.
Could FeatureGateAttribute
itself implement IPageFilter
and IAsyncPageFilter
?
from featuremanagement-dotnet.
services
.AddRazorPages(options =>
{
...
options.Conventions.AddAreaFolderApplicationModelConvention("Admin", "/Customers", cOption =>
{
cOption.Filters.Add(new RazorPageFeatureGate(ApplicationFeatureFlags.ManageCustomer));
});
})
Apply feature gate filter to area folder
from featuremanagement-dotnet.
We already implemented a a very simple IAsyncPageFilter with similar implementation provided by @haacked and it's nicely working:
I suggest you make a PR from this. Worked like a charm ! Thanks for sharing
from featuremanagement-dotnet.
Since page filters and action filters are executed in isolation we can add this new functionality in the existing FeatureGateAttribute
. I have a sent out a PR #166.
from featuremanagement-dotnet.
Related Issues (20)
- Incorrect NuGet Package Information? HOT 2
- .Net 6 - Feature not updating in app HOT 10
- Feature Request: Add "Not" to RequirementType to disable endpoint using FeatureGateAttribute when flag set to true HOT 1
- ConfigurationFeatureFlagDefinitionProvider Fails to "override" flags due to "GetOrAdd"
- Blazor Server HOT 2
- Synchronous Evaluation HOT 2
- Feature flag is not refreshing in WPF (.NET Framework 4.7.2) HOT 10
- Targeted Feature does not honor zero percent HOT 3
- How stable are dynamic features? HOT 2
- Adding Instrumentation code
- Can I use Microsoft Feature Management – Feature Flags in other than .NET Core Frameworks ? HOT 1
- Local configuration and remote configuration HOT 2
- Unit Testing Custom Filter HOT 3
- Support of Targeting(percentage) and custom filter HOT 10
- How to Get All Feature Flags? HOT 10
- FeatureFilter not found exception HOT 4
- Infinite hang on configurationBuilder.Build() HOT 4
- CustomFilter breaks when upgrading to 2.6.0 with null reference exception HOT 5
- IgnoreMissingFeatureFilters should not be false by default HOT 5
- Authentication failed because the remote party has closed the transport stream HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from featuremanagement-dotnet.