Comment vérifier si la méthode a un atsortingbut

J’ai un exemple de classe

public class MyClass{ ActionResult Method1(){ .... } [Authorize] ActionResult Method2(){ .... } [Authorize] ActionResult Method3(int value){ .... } } 

Maintenant, ce que je veux, c’est d’écrire une fonction retournant vrai / faux qui peut être exécutée comme ceci

 var controller = new MyClass(); Assert.IsFalse(MethodHasAuthorizeAtsortingbute(controller.Method1)); Assert.IsTrue(MethodHasAuthorizeAtsortingbute(controller.Method2)); Assert.IsTrue(MethodHasAuthorizeAtsortingbute(controller.Method3)); 

Je suis arrivé au point où

 public bool MethodHasAuthorizeAtsortingbute(Func function) { return function.Method.GetCustomAtsortingbutes(typeof(AuthorizeAtsortingbute), false).Length > 0; } 

fonctionnerait pour Method3. Maintenant, comment puis-je faire ce générique de manière à ce qu’il prenne également des chaînes et des classes comme parameters?

    Le problème avec votre code est la signature de public bool MethodHasAuthorizeAtsortingbute(Func function) . MethodHasAuthorizeAtsortingbute ne peut être utilisé qu’avec des arguments correspondant à la signature du délégué que vous avez spécifié. Dans ce cas, une méthode renvoyant un ActionResult avec un paramètre de type int .

    Lorsque vous appelez cette méthode comme MethodHasAuthorizeAtsortingbute(controller.Method3) , le compilateur effectue une conversion de groupe de méthodes. Cela n’est peut-être pas toujours souhaitable et peut produire des résultats inattendus (les conversions de groupe de méthodes ne sont pas toujours simples). Si vous essayez d’appeler MethodHasAuthorizeAtsortingbute(controller.Method1) vous obtiendrez une erreur du compilateur car il n’y aura pas de conversion.

    Une solution plus générale peut être construite avec des arbres d’expression et le fameux truc “MethodOf”. Il utilise des arbres d’expression générés par le compilateur pour trouver la cible d’appel:

     public static MethodInfo MethodOf( Expression expression ) { MethodCallExpression body = (MethodCallExpression)expression.Body; return body.Method; } 

    Vous pouvez l’utiliser comme ceci, mais vous pouvez aussi l’utiliser avec n’importe quelle méthode:

     MethodInfo method = MethodOf( () => controller.Method3( default( int ) ) ); 

    Cela fait, nous pouvons construire une implémentation générale:

     public static bool MethodHasAuthorizeAtsortingbute( Expression expression ) { var method = MethodOf( expression ); const bool includeInherited = false; return method.GetCustomAtsortingbutes( typeof( AuthorizeAtsortingbute ), includeInherited ).Any(); } 

    Ok, c’est pour les méthodes. Maintenant, si vous souhaitez appliquer le contrôle d’atsortingbut sur des classes ou des champs à (je vais épargner des propriétés car ce sont en fait des méthodes), nous devons effectuer notre contrôle sur MemberInfo , qui est la racine d’inheritance de Type , FieldInfo et MethodInfo . Ceci est aussi simple que d’extraire la recherche d’atsortingbuts dans une méthode séparée et de fournir des méthodes d’adaptateur appropriées avec des noms sympas:

     public static bool MethodHasAuthorizeAtsortingbute( Expression expression ) { MemberInfo member = MethodOf( expression ); return MemberHasAuthorizeAtsortingbute( member ); } public static bool TypeHasAuthorizeAtsortingbute( Type t) { return MemberHasAuthorizeAtsortingbute( t ); } private static bool MemberHasAuthorizeAtsortingbute( MemberInfo member ) { const bool includeInherited = false; return member.GetCustomAtsortingbutes( typeof( AuthorizeAtsortingbute ), includeInherited ).Any(); } 

    Je vais laisser la mise en œuvre pour les champs comme exercice, vous pouvez utiliser le même truc que MethodOf.

    Il existe une solution plus simple que celle proposée ci-dessus avec la version actuelle .NET / C # (4.6.1, C # 6):

    Si vous n’avez qu’une seule méthode portant ce nom:

     var method = typeof(TestClass).GetMethods() .SingleOrDefault(x => x.Name == nameof(TestClass.TestMethod)); var atsortingbute = method?.GetCustomAtsortingbutes(typeof(MethodAtsortingbute), true) .Single() as MethodAtsortingbute; 

    Maintenant, vérifiez si vous avez l’atsortingbut défini sur la méthode:

     bool isDefined = atsortingbute != null; 

    Et si vous voulez accéder aux propriétés de l’atsortingbut, vous pouvez le faire facilement en procédant comme suit:

     var someInfo = atsortingbute.SomeMethodInfo 

    S’il existe plusieurs méthodes portant le même nom, vous pouvez continuer et utiliser method.GetParameters() et rechercher les parameters au lieu de .GetMethods().Single...

    Si vous savez que votre méthode n’a pas de paramètre, cette vérification est simple:

     var method = typeof(TestClass).GetMethods() .SingleOrDefault( x => x.Name == nameof(TestClass.TestMethod) && x.GetParameters().Length == 0 ); 

    Sinon, cela sera plus compliqué (vérification des parameters, etc.) et les autres solutions sont beaucoup plus simples et robustes à utiliser.

    Donc: utilisez ceci si vous n’avez pas de surcharge pour une méthode, ou si vous voulez seulement lire les atsortingbuts d’une méthode avec une quantité spécifiée de parameters. Sinon, utilisez la MethodOf fournie par d’autres réponses ici.

    Je fais quelque chose comme ça:

     public static bool MethodHasAuthorizeAtsortingbute(this Delegate pMethod, ssortingng pRoleAccess) { var mi = pMethod.GetMethodInfo(); const bool includeInherited = false; var atr = mi.GetCustomAtsortingbutes(typeof(AuthorizeAtsortingbute), includeInherited) .Select(t => (AuthorizeAtsortingbute)t) .Where(t => pRoleAccess.Length>0?t.Roles == pRoleAccess:true); if (pRoleAccess == Ssortingng.Empty) { return !atr.Any(); } else { return atr.Any(); } } public static bool MethodHasAllowAnonymousAtsortingbute(this Delegate pMethod) { var mi = pMethod.GetMethodInfo(); const bool includeInherited = false; var atr = mi.GetCustomAtsortingbutes(typeof(AllowAnonymousAtsortingbute), includeInherited); return atr.Any(); } 

    L’appel suit

     Func func = controller.Login; bool atrAuthorize = func.MethodHasAuthorizeAtsortingbute(Ssortingng.Empty); 

    Trouvez un exemple où je trouve les méthodes d’une classe auxquelles un atsortingbut spécifié est appliqué.

     private static void GetMethodInfo(object className) { var methods = className.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach(var m in methods) { var parameters = m.GetParameters(); var att = m.GetCustomAtsortingbutes(typeof (CustomAtsortingbute), true); } } 

    Le paramètre qui est passé est une instance d’une classe. Vous pouvez modifier le code en fonction de vos besoins, ce qui devrait être assez simple.