简体   繁体   English

如何在自定义属性中找到修饰的方法?

[英]How can I find the decorated method from within a custom attribute?

I need to do some custom authorization based on specific methods in my controllers. 我需要根据控制器中的特定方法进行一些自定义授权。 Is it possible for a custom attribute to know which method is being called? 自定义属性是否可能知道正在调用哪个方法?

Given the following: 给定以下内容:

[CustomAttribute]
public ActionResult Index()
{
    //some stuff
}

Is it possible for [CustomAttribute] to know that Index that called specifically? [CustomAttribute]是否可以知道专门调用的那个Index? The same would apply to any other method decorated with [CustomAttribute]. 这同样适用于用[CustomAttribute]装饰的任何其他方法。

In MVC controller methods are called Actions. 在MVC控制器中,方法称为“动作”。

You can figure out which action has been called from inside your attribute by having your attribute inherit from ActionFilterAttribute. 您可以通过让属性继承自ActionFilterAttribute来确定已从属性内部调用了哪个动作。 You then override the OnActionExecuting method (or OnActionExecuted). 然后,您重写OnActionExecuting方法(或OnActionExecuted)。 The filterContext (ActionExecutingContext) argument has a property called ActionDescriptor. filterContext(ActionExecutingContext)参数具有一个称为ActionDescriptor的属性。 you can get the action name from the ActionName property. 您可以从ActionName属性获取操作名称。

var actionName = filterContext.ActionDescriptor.ActionName

I am not sure that I understand your question fully, but I will try to answer. 我不确定我是否完全理解您的问题,但是我会尽力回答。 The attributes are used to mark a method or a class. 这些属性用于标记方法或类。 Imagine it as a tag. 想象一下它是一个标签。 It is not an instance having behaviour and you cannot make decisions inside the attribute. 它不是具有行为的实例,您不能在属性内做出决定。 You should use attribute annotations to make decisions in your methods and not the opposite. 您应该使用属性注释在方法中做出决策,而不是相反。

Since you want to make custom authorization decisions, I would suggest using a custom Membership API provider . 由于您要做出自定义授权决定,因此建议您使用自定义会员API提供程序 There, you could use the attributes of the current index method to make your custom decisions. 在那里,您可以使用当前索引方法的属性来进行自定义决策。 I would use reflection to get the executing action or controller, using the next statements: 我将使用以下语句使用反射来获取执行动作或控制器:

string actionName = this.ControllerContext.RouteData.Values["action"];
string controllerName = this.ControllerContext.RouteData.Values["controller"];

Then, using reflection you could also retrieve the info for the specific class and method and check the attributes decorating the respective objects. 然后,您还可以使用反射来获取特定类和方法的信息,并检查装饰各个对象的属性。 This MSDN post could explain how you could access the attributes of a specific method. 这篇MSDN帖子可以解释您如何访问特定方法的属性。

Hope I helped! 希望我能帮上忙!

A custom attribute is a static piece of information attached to a code entity (property, method, field,). 定制属性是附加到代码实体(属性,方法,字段)的静态信息。 So, what you require is not possible. 因此,您所需要的是不可能的。

The standard way of letting "someone" know that something is happening, is to use an event. 让“某人”知道某事正在发生的标准方法是使用事件。 Those can be static, if they concern the entire type and not just an instance. 如果它们涉及整个类型而不仅仅是实例,那么它们可以是静态的。

First define an EventArgs class: 首先定义一个EventArgs类:

public class IndexCalledEventArgs : EventArgs
{
    public IndexCalledEventArgs(int index)
    {
        Index = index;
    }

    public int Index { get; private set; }
}

Your class whose index has to be observed defines the static event and fires it when the index is accessed: 必须遵守其索引的类定义了静态事件,并在访问索引时将其触发:

public class MyClass
{
    public static event EventHandler<IndexCalledEventArgs> IndexCalled;

    public ActionResult Index()
    {
        int index;

        // Somehow get an index
        index = 7;
        OnIndexCalled(this, index);

        return new ActionResult { Index = index };
    }

    private static void OnIndexCalled(MyClass sender, int index)
    {
        var handler = IndexCalled;
        if (handler != null) {
            // Create the event args and fire the event.
            handler(sender, new IndexCalledEventArgs(index));
        }
    }
}

An object who wants to observe this event, attaches to it: 想要观察此事件的对象附加到它:

public class InteresedInIndexCalledEvent
{
    public InteresedInIndexCalledEvent()
    {
        MyClass.IndexCalled += MyClass_IndexCalled;
    }

    void MyClass_IndexCalled(object sender, IndexCalledEventArgs e)
    {
        Console.WriteLine("Index {0} was called", e.Index);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM