Question

My sample project is a MVC WebApi project.

The standard AuthorizeAttribute takes a Roles = "" or Users = "" parameter. I didn't have a look at the implementation yet, but I don't want to either :) Can you make this a little bit more dummy proof with expressions? In a way that you get a compile time error when you decide to rename the attribute's "Roles" property to anything else?

public interface IControllerContext
{
    int MagicNumber { get; }
    int ScaryNumber { get; }
    string Version { get; }
}

public class AppAuthorizationAttribute : FilterAttribute
{
    public IControllerContext SomeControllerContext
    {
       get; // implementation omitted
    }

    // ...
}

// This is my sample class which needs to be validated using the attribute.
public class TestClass : BaseClass
{
    [AppAuthorization((n) => n.MagicNumber == 13)] // or literally: which property and how to validate it"
    protected void SomeMethodWhichRequiresPreProcessingValidation()
    {
        // do something.
        // inside here I have access to an instance of ISomeContext
        // and can do anything I want.
    }
}

Optional bonus question: Would it somehow be possible to access a field of the current controller (not static) from within the attribute definition? It would be a cool thing to inject a controller field into the validation lambda expression. Something like that: AppAuthorization((controller) => controller.SomePropertyHere.MagicNumer == 13)

Was it helpful?

Solution

Attribute declaration can only use simple types and constants. The compiler will not allow you to use expressions so your planned approach will not work.

You also cannot reference fields or properties, just constants. The closest you could get is something along the lines of

public const MagicNumberPropertyName = "MagicNumber";
public enum Operator
{
    Equals
}

[AppAuthorization(MagicNumberPropertyName, Operator.Equals, 13)]
protected void Method() {}

OTHER TIPS

Here is the example , where you can use Enum for Authorise attribute , you can write your logic inside authorise

 /// <summary>
    /// Class RoleAuthorizeAttribute.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class RoleAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="RoleAuthorizeAttribute"/> class.
        /// </summary>
        /// <param name="roles">The roles.</param>
        /// <exception cref="System.ArgumentException">The roles parameter may only contain enums;roles</exception>
        public RoleAuthorizeAttribute(params object[] roles)
        {
            if (roles.Any(r => r.GetType().BaseType != typeof (Enum)))
            {
                throw new ArgumentException(
                    "The roles parameter may only contain enums",
                    "roles");
            }
            Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r)).ToList());
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top