2011-09-21 2 views
3

Lors des tests (au moins), nous enregistrons des informations de bas niveau pour chaque contrôleur/action. Tous les contrôleurs sont dérivés de notre BaseController personnalisé qui remplace OnActionExecuting pour effectuer la journalisation.Attribut d'action personnalisée MVC

Nous avons une propriété dans le BaseController qui détermine si cette journalisation se produira ou pas, de sorte qu'un contrôleur peut remplacer OnActionExecuting lui-même, réinitialiser l'indicateur, puis appeler "base.OnActionExecuting". Le drapeau est normalement vrai, mais nous voudrions le désactiver pour certaines requêtes JSON, par exemple.

Ce que nous préférons faire est de créer un contrôleur personnalisé/filtre d'action pour gérer cela, quelque chose comme ceci:

[LogPageAccess(false)] 
[HttpGet] 
Public ActionResult Foobar() 

Je suis sûr qu'il ya une façon de le faire, mais je ne été capable de comprendre comment créer l'attribut personnalisé et le faire réinitialiser le drapeau dans le BaseController.

Merci ...

Répondre

2

dans mon projet, je l'utilise comme suit pour vérifier les contrôleurs d'accès:

[Capability(UserCapability.FileManagement)] 
    public ActionResult FileList(FileListRequestModel request, bool ajax = false) 
    { 
     //code 
    } 

Voici ma classe de capacité

/// <summary> 
/// Decorator to MVC class and method to evaluate if a certain capability is enabled 
/// </summary> 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 
public class CapabilityAttribute : AuthorizeAttribute 
{ 
    #region Class Attributes 

    private object _capability = null; 

    #endregion 

    #region Public Methods 

    /// <summary> 
    /// Create a new capability attribute 
    /// </summary> 
    /// <param name="capability">Context Value passed to the validator</param> 
    public CapabilityAttribute(object capability) 
    { 
     this._capability = capability; 
    } 

    /// <summary> 
    /// Check if attribute is enabled 
    /// </summary> 
    /// <param name="filterContext"></param> 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (!Capability.Enabled(this._capability)) 
     { 
      throw new UnauthorizedAccessException(); 
     } 
     else 
     { 
      base.OnAuthorization(filterContext); 
     } 
    } 

    #endregion 
} 

Vous avez juste besoin d'adapter ce code pour votre cas, j'espère qu'il deviendra utile

+0

Avait besoin de quelque chose de similaire, et cela m'a eu où je devais aller. Au lieu de lancer un 'UnauthorizedAccessException' cependant, j'ai utilisé' filterContext.Result = new HttpUnauthorizedResult(); 'que je me sens mieux dans la page MVC. Vous pouvez consulter [la documentation de MSDN pour 'UnauthorizedAccessException'] (http://msdn.microsoft.com/en-us/library/system.unauthorizedaccessexception.aspx) pour comprendre pourquoi je n'ai pas trouvé cela approprié dans ce cas. –

0

J'ai essayé de construire un simple examp Je me suis alors rendu compte que je ne pouvais pas passer les données d'instance à un Attribute - donc si je mets un drapeau Log à false, je ne pourrais pas l'utiliser pour manipuler directement la propriété du contrôleur de base.

Check out this SO post.

Voici était le code que je jouais avec (ne compile pas - ne peut pas passer this):

public class BaseController : Controller 
{ 
    public bool LogPageRequests { get; set; } 
} 

public class LogPageAccess : ActionFilterAttribute 
{ 
    public LogPageAccess(BaseController baseController, bool log = true) 
    { 
     baseController.LogPageRequests = log; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     //Do Whatever 
     base.OnActionExecuting(filterContext); 
    } 
} 

public class SomeController : BaseController 
{ 
    [LogPageAccess(this, false)] 
    public ActionResult Index() 
    { 
     return View(); 
    } 
} 

Peut-être que vous pouvez faire quelque chose avec la réflexion, mais il pourrait être le cas que vous » Vous devrez le faire comme vous l'avez fait car il ne semble pas possible d'obtenir des données d'instance pour l'attribut.

+0

Vous pouvez obtenir le contrôleur du contexte. – SLaks

+0

@SLaks Pourriez-vous me donner un exemple rapide et sale? – davecoulter

+0

'filterContext.Controller' – SLaks

Questions connexes