Question

We are trying to create a more specific [Authorize] Attribute for Asp.Net MVC

 [AttributeUsage(AttributeTargets.All)] 
    public class AuthoriseUser : System.Attribute
    {
        public AuthoriseUser(string PermRequest)
        {
            //Do Some Auth.
        }
    }

and we call this like so,

[AuthoriseUser("CanViewRoles")]

But when debugging the function is never called.

Now we are obviously doing somthing very wrong, I've seen PostSharp but due to the nature of the project I cant use it. How can i achieve this using just .Net?

Was it helpful?

Solution

Attributes are not meant for playing functional role. You need to write code using reflection somewhere in your project that reads type-meta-data of classes [and props, methods, etc.] and finds attributes applied to it. Based on the attributes applied you can take decisions at run-time about what to do with that. Generally this is done in base classes of your library.

As an example in our projects we have an attribute called 'Searchable'. This attribute is applied to properties of business objects which need to be included in search. When the client calls Search method we filter out all props that are decorated with Searchable attribute and then construct query to do search on the database. Practically we dont have any code related to search functionality in SearchableAttribute class - in fact there's no code at all in SearchableAttribute class.

Example Code:

SearchableAttribute

/// <summary>
/// Holds mapping information of searchable fields of business objects.
/// </summary>
[global::System.AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public sealed class SearchableAttribute : Attribute
{
    /// <summary>
    /// Initializes a new instance of the SearchableAttributeAttribute class.
    /// </summary>
    public SearchableAttribute()
    {
    }
}

A method in business object base class

    /// <summary>
    /// Provides collection of all Searchable Fields.
    /// </summary>
    /// <returns>DataField collection</returns>
    public IQueryable<DataField> GetSearchableDataFields()
    {
        PropertyInfo[] properties =
            this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

        var entityFields = from PropertyInfo property in properties
                           where property.GetCustomAttributes(typeof(SearchableAttribute), true).Length > 0
                           select
                               new DataField(
                                   property,
                                   (SearchableAttribute)property.GetCustomAttributes(typeof(SearchableAttribute), true)[0]);

        return entityFields.AsQueryable();
    }

OTHER TIPS

Would you not need to derive your class from AuthorizeAttribute? See Custom Authorization in the ASP.NET MVC Framework and Authorize Attribute

An attribute is used to 'decorate' a method / property / class, so that you can give an additional/extra meaning to that method.

By decorating a method with a certain attribute, this does not mean that the 'attribute' gets executed whenever you call that method. If you want that behaviour, you will indeed have to take a look at a code-weaver, like PostSharp for instance, to weave additional code to the methods / properties you've decorated with an attribute.

Attributes in .NET are used to decorate a class or method, but you need to write code to request this information. For example to verify that a class is decorated with your custom attribute you could use something like this:

var attributes = (AuthoriseUser[])typeof(YourType)
    .GetCustomAttributes(typeof(AuthoriseUser), true);

Then you can read the metadata associated with this attribute.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top