2010-01-07 28 views
5

Tengo una clase base con un atributo y quiero ocultarlo en una clase derivada. ¿Hay alguna manera de hacer esto que no sea el uso de la reflexión?C# ocultar Atributo en la clase derivada

[Authorize(Roles = "User,Admin,Customs")] 
public abstract class ApplicationController : Controller 
{ 
} 

// hide the Authorize attribute 
public class ErrorController : ApplicationController 
{ 
} 
+0

Por alguna razón, estoy confundido acerca de esto Q. –

+0

Si esto es sobre MVC, por favor Marquelo como tal. –

+0

¿Le gusta no poder ver con reflexión que la clase base está decorada con ese atributo? –

Respuesta

2

Puede anular AuthorizeAttribute con su propia clase y especificar que no se herede.

[AttributeUsage(AttributeTargets.Class, Inherited=false)] 
public class NonInheritedAuthorizeAttribute : AuthorizeAttribute 
{ 
    // Constructors, etc. 
} 

Ahora puede especificar qué clase utilizar, siempre y cuando tenga ApplicationController.

+0

Pensé en hacer esto también, pero trato de usar clases de Microsoft siempre que sea posible, así que opté por eliminar el atributo Autorizar de mi clase base y agregarlo a cada controlador derivado. – PaulN

+0

+1 para 'Inherited = false', no sobre MVC, pero asegúrese de que la clase/método derivado no intente modificar las propiedades del atributo. – CallMeLaNN

1

Depende un poco de lo que quiere decir con 'Ocultar'. Usted debe ser capaz de revocar la autorización de esta manera:

// hide the Authorize attribute 
[Authorize(Roles = "")] 
public class ErrorController : ApplicationController 
{ 
} 
+1

Esto es exactamente lo que quiero hacer (permitir que una persona no autorizada vea la Vista). Desafortunadamente, AuthorizeAttribute comprueba primero si (! User.Identity.IsAuthenticated) valida los Roles. Es por eso que quiero "Ocultar" o eliminar el atributo de la clase base solo para la clase ErrorController. – PaulN

+2

Quizás debería reconsiderar el diseño de herencia: invente una nueva clase base y obtenga ambos controladores de eso. –

2

Si se trata de un método/prop, que podría volver a declarar (new) el miembro sin el atributo infractor. No sé de ninguna manera con los atributos de nivel de clase.

public new SomeType Foo() { return base.Foo(); } 
0

Puede especificar el atributo 'AttributeUage' en su clase de atributos, como esto:

[AttributeUsage(AttributeTargets.Class, Inherited=false)] 
public class AuthorizeAttribute : Attribute 
{ 
} 

A continuación, las clases que se derivan de la clase donde se ha aplicado el atributo, no heredarán el atributo.

Ow, ahora me doy cuenta de que el atributo Autorizar no es un atributo personalizado.

+0

Sí, esta es una clase creada por el equipo de Microsoft en System.Web.MVC. – PaulN

3

La eliminación de características heredadas de una clase base infringe Liskov Substitution Principle. Romper la herencia de esta manera generalmente muestra su fea cabeza con consecuencias no deseadas e inesperadas — después de que sea demasiado tarde para cambiar el problema de raíz.

Así que incluso si hay una manera, le responderé que no debe usarla la gran mayoría de las veces. Pueden aplicarse alternativas a la herencia, como la contención (tiene-un en lugar del de la herencia is-a) o la refactorización de la base en una interfaz separada que ambos pueden implementar; o incluso combinar ambos.

+0

Bueno, hubiera sido bueno establecer una autorización predeterminada para el sitio usando la clase base. Solo tengo 1 Controlador de 9 que solo permite Admins. Dado que no parece posible eliminar un atributo de clase base, este es el consejo más acertado.He eliminado [Autorizar (Roles = "Usuario, Administrador, Aduanas")] y lo voy a configurar en cada controlador. – PaulN

+0

Los atributos no son como los miembros de la clase, y no son necesariamente heredados (es por eso que hay 'AttributeUsage (Inherited = false)'). Entonces LSP no se aplica necesariamente aquí. –

Cuestiones relacionadas