2011-03-19 3 views
2

Je viens de remarquer un comportement étrange avec la priorité ActionFilterAttribute dans MVC3. Il s'avère que si un Contrôleur et une Action sont décorés avec le même ActionFilterAttribute avec AllowMultiple = false (la valeur par défaut), alors celui avec la valeur de commande HIGHER est sélectionné. Dans le cas d'une égalité (c'est-à-dire que les deux valeurs de commande sont les mêmes), le filtre de l'action est sélectionné. J'avais toujours pensé que le filtre sur l'action serait toujours sélectionné (s'il y en a un), quelle que soit la valeur de la commande. Exemples:ASP.NET MVC3 ActionFilterAttribute Priorité/Sélection - Bizarre?

Filtrer sur action est sélectionnée:

[MyActionFilter(Name = "Controller")] // same as Order = -1 
public class HomeController : Controller { 

    [MyActionFilter(Name = "Action")] // same as Order = -1 
    public ActionResult Index() { 
     return Content("Hello"); 
    } 

} 

Filtrer sur le contrôleur est sélectionné:

[MyActionFilter(Name = "Controller", Order = 1)] 
    public class HomeController : Controller { 

     [MyActionFilter(Name = "Action")] // same as Order = -1 
     public ActionResult Index() { 
      return Content("Hello"); 
     } 

    } 

filtre sur l'action est sélectionnée:

[MyActionFilter(Name = "Controller", Order = 1)] 
public class HomeController : Controller { 

    [MyActionFilter(Name = "Action", Order = 1)] 
    public ActionResult Index() { 
     return Content("Hello"); 
    } 

} 

filtre sur le contrôleur est sélectionné:

[MyActionFilter(Name = "Controller", Order = 20)] 
public class HomeController : Controller { 

    [MyActionFilter(Name = "Action", Order = 1)] 
    public ActionResult Index() { 
     return Content("Hello"); 
    } 

} 

Est-ce un bug ou par la conception? J'utilise MVC depuis la version 1 et je n'ai jamais remarqué cette priorité de sélection de filtre. Est-ce que ça a toujours été comme ça?

Merci

Répondre

3

Si vous définissez AllowMultiple = false et ont le même filtre d'action sur le contrôleur et l'action celui sur le contrôleur est jamais exécuté. Si vous définissez AllowMultiple=true, c'est le filtre sur le contrôleur qui est exécuté en premier en supposant le même ordre.

La chose qui a changé dans ASP.NET MVC 3 est la suivante:

Dans les versions précédentes d'ASP.NET MVC, filtres d'action sont crées par demande sauf dans quelques cas. Ce comportement n'a jamais été un comportement garanti, mais simplement un détail de mise en œuvre et le contrat pour les filtres était de les considérer comme apatrides. Dans ASP.NET MVC 3, les filtres sont mis en cache de façon plus agressive . Par conséquent, tous les filtres d'action personnalisés qui stockent incorrectement l'état d'instance peuvent être rompus.

Donc, pour assurer que vous êtes bien tester ceci:

[AttributeUsage(AttributeTargets.All, AllowMultiple = true)] 
public class MyActionFilterAttribute : ActionFilterAttribute 
{ 
    public string Name { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
Put a breakpoint here and inspect the value of the Name property ====> 
     var name = Name; 
     base.OnActionExecuting(filterContext); 
    } 
} 
+1

Merci Darin, mais je vois un autre résultat que ce que vous dites. Je définis AllowMultiple = false. Si sur l'attribut du contrôleur, j'ai mis Ordre = 1 et sur l'action avec le même attribut, je ne mets pas de commande, alors l'attribut sur le contrôleur est exécuté. Je vérifie cela en faisant System.Diagnostics.Debug.WriteLine (Name) dans le remplacement OnActionExecuting de l'attribut. Pouvez-vous s'il vous plaît exécuter votre exemple avec une valeur de commande plus élevée sur l'attribut du contrôleur et confirmer que l'attribut sur votre contrôleur n'est en effet jamais exécuté? Merci. –