6

I'm trying to write some middleware and need to know if the current action method (if any) has a particular filter attribute, so I can change behaviour based it's existence.

So is it possible to get a filters collection of type IList<IFilterMetadata> like you do on the ResourceExecutingContext when you are implementing an IResourceFilter?

0

3 Answers 3

11
+50

It's not really possible today.

It is possible in ASP.NET Core 3.0

app.UseRouting();


app.Use(async (context, next) =>
{
    Endpoint endpoint = context.GetEndpoint();

    YourFilterAttribute filter = endpoint.Metadata.GetMetadata<YourFilterAttribute>();

    if (filter != null)
    { 

    }

    await next();
});


app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});
Sign up to request clarification or add additional context in comments.

1 Comment

Is this now possible in ASP.NET Core 3.0? In particular, I have a RewriteContext from the response rewrite middleware.
5

ASP.NET Core 3.0 uses a new routing which every action is an Endpoint and all attributes on the action and the controller exists on Metadata.

Here's how you can do it.

app.UseRouting();


app.Use(async (context, next) =>
{
    Endpoint endpoint = context.GetEndpoint();

    YourFilterAttribute filter = endpoint.Metadata.GetMetadata<YourFilterAttribute>();

    if (filter != null)
    { 

    }

    await next();
});


app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

1 Comment

This is the same exact code from the prior post (which you edited to contain that) so is now a duplicate answer
0

Note: Not really answering directly your question, but may help depending of your needs (and the code is too long for comments)

Note 2: Not sure if it works on Core, if it doesn't, tell me and I remove the answer

You can know, in a filter, if another filter is used along with:

public class OneFilter : ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Check if the Attribute "AnotherFilter" is used
        if (filterContext.ActionDescriptor.IsDefined(typeof(AnotherFilter), true) || filterContext.Controller.GetType().IsDefined(typeof(AnotherFilter), true))
        {
            // things to do if the filter is used

        }
    }
}

public class AnotherFilter : ActionFilterAttribute, IActionFilter
{
   // filter things
}

AND/OR

You can put some data in the Route data to let know the Action which Filters are used:

void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
    filterContext.RouteData.Values.Add("OneFilterUsed", "true");
    base.OnActionExecuting(filterContext);
}

...

public ActionResult Index()
{
    if(RouteData.Values["OneFilterUsed"] == "true")
    {

    }

    return View();
}

2 Comments

IsDefined doesn't exist in .Net Core's ActionDescriptor.
Yeap, there is no IsDefined(), but the following can be used: if (filterContext.Filters.Any(x => filters.Contains(typeof(AnotherFilter)));) { // things to do... }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.