7
votes

C # Masquer l'attribut en classe dérivée

J'ai une classe de base avec un attribut et je veux le cacher dans une classe dérivée. Y a-t-il un moyen de faire cela autre que d'utiliser la réflexion?

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

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


4 commentaires

Pour une raison quelconque, je suis confus à propos de ce Q.


Si cela est à propos de MVC, veuillez l'étiqueter comme tel.


Comme ne pas être capable de voir avec réflexion que la classe de base est décorée avec cet attribut?


N'est pas system.web.mvc.allowanonymousattribute ce que vous voulez (ed)?


5 Réponses :


1
votes

dépend un peu sur ce que vous entendez par "cache". Vous devriez être capable de révoquer l'autorisation comme celle-ci:

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


2 commentaires

C'est exactement ce que je veux faire (permettre à une personne non autorisée de voir la vue). Malheureusement, l'autorateur-Authorizeattribute vérifie la première fois si (! User.entity.isauthenticiated) alors il valide les rôles. C'est pourquoi je veux "masquer" ou supprimer l'attribut de la classe de base pour simplement la classe ErrorController.


Peut-être devriez-vous reconsidérer la conception d'héritage: inventer une nouvelle classe de base et dériver les deux contrôleurs de cela.



2
votes

S'il s'agissait d'une méthode / accessoire, vous pouvez refroidir ( nouveau code>) le membre sans l'attribut incriminé. Je ne connais pas d'une manière avec des attributs de niveau de classe.

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


0 commentaires

0
votes

Vous pouvez spécifier l'attribut "attributeuge" de votre classe d'attribut, comme celui-ci: xxx

puis, des classes qui dérivent de la classe où vous avez appliqué l'attribut, n'héritera pas le attribut.

ow, maintenant je réalise que l'attribut Authorize n'est pas un attribut personnalisé.


1 commentaires

Oui, il s'agit d'une classe créée par l'équipe Microsoft dans System.Web.mvc.



3
votes

Vous pouvez remplacer l'Authorizeattribute avec votre propre classe et le préciser à ne pas être hérité.

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


2 commentaires

J'ai également pensé à le faire aussi, mais j'essaie d'utiliser des classes Microsoft si possible, alors j'ai choisi de supprimer simplement l'attribut Autoriser de ma classe de base et de l'ajouter à chaque contrôleur dérivé.


+1 pour héritéd = false , pas sur MVC mais assurez-vous que la classe / méthode dérivée n'essaye pas de modifier les propriétés d'attribut.



3
votes

Suppression de fonctionnalités héritées d'une classe de base viole le Principe de substitution de Liskov . briser l'héritage de cette manière arrive généralement sa tête laide avec des conséquences inattendues et inattendues - après qu'il est trop tard pour changer le problème des racines.

Donc, même s'il y a un moyen, je vais répondre à ce que vous ne devriez pas l'utiliser la grande majorité du temps. Les alternatives à l'héritage peuvent s'appliquer, telles que le confinement ( haussant-un au lieu d'héritage is-a ) ou refactoring la base dans une interface distincte que les deux peuvent ensuite mettre en œuvre; ou même combiner ces deux ces deux.


2 commentaires

Eh bien, cela serait bien de définir une autorisation par défaut pour le site à l'aide de la classe de base. Je n'ai que 1 contrôleur sur 9 qui permet seulement des administrateurs. Comme il ne semble pas possible de supprimer un attribut de classe de base, il s'agit du conseil le plus sain. J'ai supprimé [Autoriser (Roles = "utilisateur, admin, la douane")] et je vais simplement la définir dans chaque contrôleur.


Les attributs ne sont pas comme des membres de la classe et ne sont pas nécessairement hérités (c'est pourquoi il y a attributeUnage (hérité = faux) ). Donc, le LSP ne s'applique pas nécessairement ici.