23

This used used to work with earlier version of .Net. What's the equivalent in .net core terms. Now I get following error:

'ActionDescriptor' does not contain a definition for 'GetCustomAttributes' and no extension method 'GetCustomAttributes' accepting a first argument of type 'ActionDescriptor' could be found

public virtual void SetupMetadata(ActionExecutingContext filterContext)
{
    var myAttr = filterContext.ActionDescriptor.GetCustomAttributes(typeof(MyAttribute), false);
    if (myAttr.Length == 1)
        //do something
}

Attribute definition:

public class MyAttribute : Attribute
{
    private readonly string _parameter;

    public PageTitleAttribute(string parameter)
    {
        _parameter = parameter;
    }

    public string Parameter { get { return _parameter; } }
}

Code Usage:

[MyAttribute("Attribute value is set here")]
public ActionResult About()
{
    ViewBag.Message = "Your application description page.";
    return View();
}

4 Answers 4

33

Hope to help others, here's what i did:

var attrib = (filterContext.ActionDescriptor as ControllerActionDescriptor).MethodInfo.GetCustomAttributes<MyAttribute>().FirstOrDefault();
Sign up to request clarification or add additional context in comments.

1 Comment

For those looking to do the same for a parameter: cast a ControllerActionDescriptor.Parameters to ControllerParameterDescriptor which has a ParameterInfo for all the usual reflection information.
16

Another option without needing a runtime cast:

public class MyAttribute :  Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute {
  // same content as in the question
}

By inheriting from ActionFilterAttribute, your attribute will now appear in the ActionDescriptor.FilterDescriptors collection, and you can search that:

public virtual void SetupMetadata(ActionExecutingContext filterContext)
{
    var myAttr = filterContext.ActionDescriptor
        .FilterDescriptors
        .Where(x => x.Filter is MyAttribute)
        .ToArray();
    if (myAttr.Length == 1) {
        //do something
    }
}

I'm unsure if this is dirtier or cleaner than casting to ControllerActionDescriptor, but it's an option if you control the attribute.

1 Comment

A more direct way could be bool isAttributeSet = filterContext.ActionDescriptor.FilterDescriptors.Any(fd => fd.Filter is MyAttribute);
9

For ASP.NET Core 3+:

    var filters = context.Filters;
    // And filter it like this: 
    var filtered = filters.OfType<OurFilterType>();

Comments

3

Why not use:

filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(MyAttribute), false).Any()

1 Comment

This just gets controller's attributes not action's attributes.

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.