Pregunta

Estamos intentando crear un atributo [Autorizar] más específico para Asp.Net MVC

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

y llamamos a esto así,

[AuthoriseUser("CanViewRoles")]

Pero al depurar la función nunca se llama.

Obviamente estamos haciendo algo muy mal, he visto PostSharp pero debido a la naturaleza del proyecto no puedo usarlo. ¿Cómo puedo lograr esto usando solo .Net?

¿Fue útil?

Solución

Los atributos no están diseñados para desempeñar un papel funcional. Debe escribir código utilizando la reflexión en algún lugar de su proyecto que lea metadatos de tipo de clases [y accesorios, métodos, etc.] y encuentre los atributos que se le aplican. En función de los atributos aplicados, puede tomar decisiones en tiempo de ejecución sobre qué hacer con eso. Generalmente esto se hace en clases base de su biblioteca.

Como ejemplo en nuestros proyectos, tenemos un atributo llamado 'Buscable'. Este atributo se aplica a las propiedades de los objetos comerciales que deben incluirse en la búsqueda. Cuando el cliente llama al método de búsqueda, filtramos todos los accesorios decorados con un atributo de búsqueda y luego construimos una consulta para realizar una búsqueda en la base de datos. En la práctica, no tenemos ningún código relacionado con la funcionalidad de búsqueda en la clase SearchableAttribute; de ??hecho, no hay ningún código en la clase SearchableAttribute.

Código de ejemplo:

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()
    {
    }
}

Un método en la clase base de objeto de negocio

    /// <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();
    }

Otros consejos

¿No necesitaría derivar su clase de AuthorizeAttribute ? Consulte Autorización personalizada en el Framework MVC de ASP.NET y en el atributo Authorize

Un atributo se usa para "decorar" un método / propiedad / clase, para que puedas darle un significado adicional / extra a ese método.

Al decorar un método con un determinado atributo, esto no significa que el 'atributo' se ejecute siempre que se llame a ese método. Si desea ese comportamiento, tendrá que echar un vistazo a un tejedor de código, como PostSharp, por ejemplo, para tejer código adicional a los métodos / propiedades que ha decorado con un atributo.

Los atributos en .NET se utilizan para decorar una clase o método, pero es necesario escribir código para solicitar esta información. Por ejemplo, para verificar que una clase está decorada con su atributo personalizado, podría usar algo como esto:

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

Luego puedes leer los metadatos asociados con este atributo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top