1

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)

lapsus
  • 2,915
  • 2
  • 32
  • 61
  • 1
    Do you really think that the `AppAuthorization` is attribute? – Hamlet Hakobyan Mar 12 '14 at 15:33
  • Not in the dummy code above - but assume it is. I'll update the sample. – lapsus Mar 12 '14 at 15:34
  • 1
    You cannot use lambdas as attribute parameters. For a list of valid attribute parameter types check [the msdn](http://msdn.microsoft.com/en-us/library/aa664615(v=vs.71).aspx) – Daniel J.G. Mar 12 '14 at 15:39
  • Don't really understand the specific scenario here, but outside of some of the previously mentioned limitations in prior comments, you could possibly add extra compile time validation [using Postsharp by applying aspects](http://doc.postsharp.net/##aspect-validation). – Steven Jeuris Mar 12 '14 at 15:51

2 Answers2

4

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() {}
Knaģis
  • 20,827
  • 7
  • 66
  • 80
0

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());
        }
    }
ineffable p
  • 1,207
  • 2
  • 22
  • 46