2010-01-07 7 views
5

Ich habe eine Basisklasse mit einem Attribut und ich möchte es in einer abgeleiteten Klasse verstecken. Gibt es einen anderen Weg als die Reflexion?C# hide Attribut in abgeleiteter Klasse

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

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

Aus irgendeinem Grund bin ich verwirrt über diese Frage. –

+0

Wenn dies über MVC ist, dann bitte markieren Sie es als solches. –

+0

Wie nicht mit der Reflektion zu sehen, dass die Basisklasse mit diesem Attribut verziert ist? –

Antwort

2

Sie können das AuthorizeAttribute mit Ihrer eigenen Klasse überschreiben und angeben, dass es nicht vererbt wird.

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

Jetzt können Sie angeben, welche Klasse verwendet werden soll, solange Sie ApplicationController besitzen.

+0

Ich dachte darüber nach, dies auch zu tun, aber ich versuche, wann immer möglich Microsoft-Klassen zu verwenden, also entschied ich mich, nur das Autorize-Attribut aus meiner Basisklasse zu entfernen und es zu jedem abgeleiteten Controller hinzuzufügen. – PaulN

+0

+1 für 'Inherited = false', nicht über MVC, aber stellen Sie sicher, dass die abgeleitete Klasse/Methode nicht versucht, die Attributeigenschaften zu ändern. – CallMeLaNN

1

Hängt davon ab, was Sie mit "Verstecken" meinen. Sie sollten die Genehmigung wie diese zu widerrufen können,:

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

Dies ist genau das, was ich tun möchte (erlauben Sie einer nicht autorisierten Person, die Ansicht zu sehen). Leider überprüft das AuthorizeAttribute zuerst, ob (! User.Identity.IsAuthenticated) dann die Rollen überprüft. Also das ist, warum ich das Attribut aus der Basisklasse nur für die ErrorController-Klasse "ausblenden" oder entfernen möchte. – PaulN

+2

Vielleicht sollten Sie das Vererbungsdesign überdenken: Erfinden Sie eine neue Basisklasse und leiten Sie daraus beide Controller ab. –

2

Wenn es eine Methode/prop war, konnte man wieder declare (new) das Element, ohne das säumige Attribut. Ich kenne keine Möglichkeit mit Attributen auf Klassenebene.

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

können Sie geben das Attribut ‚AttributeUage‘ auf Ihrer Attributklasse, wie folgt aus:

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

Dann Klassen, die von der Klasse abgeleitet werden, wo Sie das Attribut angewendet haben, wird das nicht erben Attribut.

Ow, jetzt merke ich, dass das Autorize-Attribut kein benutzerdefiniertes Attribut ist.

+0

Ja, dies ist eine Klasse, die vom Microsoft-Team in System.Web.MVC erstellt wurde. – PaulN

3

Das Entfernen von Features, die von einer Basisklasse geerbt wurden, verstößt gegen die Liskov Substitution Principle. Breaking Vererbung auf diese Weise in der Regel reißt seinen hässlichen Kopf mit unbeabsichtigten und unerwarteten Folgen —, nachdem es zu spät ist, um das Root-Problem zu ändern.

Also selbst wenn es einen Weg gibt, werde ich antworten, dass Sie es die überwiegende Mehrheit der Zeit nicht verwenden sollten. Alternativen zur Vererbung können Anwendung finden, wie Containment (has-a anstelle der Vererbung ist-a) oder Refactoring der Basis in eine separate Schnittstelle, die beide dann implementieren können; oder kombinieren Sie beides.

+0

Nun, es wäre nett, eine Standardautorisierung für die Site unter Verwendung der Basisklasse festzulegen. Ich habe nur einen Controller von 9, der nur Admins erlaubt. Da es nicht möglich scheint, ein Basisklassenattribut zu entfernen, ist dies der beste Ratschlag.Ich habe [Authorize (Rollen = "Benutzer, Admin, Zoll")] entfernt und ich werde es nur in jedem Controller setzen. – PaulN

+0

Attribute sind nicht wie Klassenmitglieder und sind nicht notwendigerweise vererbt (deshalb gibt es 'AttributUsage (Inherited = false)'). Also LSP gilt nicht unbedingt hier. –