views:

284

answers:

4

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?

+3  A: 

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.

Frederik Gheysels
+4  A: 

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

James
This seems like a good option.
Pino
+2  A: 

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.

Darin Dimitrov
A: 

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();
    }
this. __curious_geek
Do you have an example of this?
Pino
code added :) :)
this. __curious_geek
Your answer is correct outside of ASP.NET MVC; However, ASP.NET MVC action filters are a special kind of attribute. They do get executed as part of the MVC pipeline, and allow you to handle certain events. http://www.asp.net/learn/mvc/tutorial-14-cs.aspx Your answer is wrong in the context of ASP.NET MVC.
Ben Robbins