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

时间:2014-03-10 18:35:27

标签: c# .net asp.net-mvc

我需要根据控制器中的特定方法进行一些自定义授权。自定义属性是否可以知道正在调用哪个方法?

鉴于以下内容:

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

[CustomAttribute]是否可以知道专门调用的索引?这同样适用于使用[CustomAttribute]修饰的任何其他方法。

3 个答案:

答案 0 :(得分:1)

在MVC控制器中,方法称为操作。

您可以通过让属性继承自ActionFilterAttribute来确定从属性中调用了哪个操作。然后重写OnActionExecuting方法(或OnActionExecuted)。 filterContext(ActionExecutingContext)参数具有名为ActionDescriptor的属性。您可以从ActionName属性中获取操作名称。

var actionName = filterContext.ActionDescriptor.ActionName

答案 1 :(得分:1)

我不确定我是否完全理解你的问题,但我会尽力回答。这些属性用于标记方法或类。想象一下它作为标签。它不是具有行为的实例,您无法在属性内做出决策。您应该使用属性注释在方法中做出决策,而不是相反。

由于您要制定自定义授权决策,我建议您使用custom Membership API provider。在那里,您可以使用当前索引方法的属性来制定自定义决策。我将使用反射来获取执行操作或控制器,使用下一个语句:

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

然后,使用反射您还可以检索特定类和方法的信息,并检查装饰相应对象的属性。 This MSDN post可以解释如何访问特定方法的属性。

希望我帮忙!

答案 2 :(得分:0)

自定义属性是附加到代码实体(属性,方法,字段)的静态信息。所以,你需要的是不可能的。

让“某人”知道某事发生的标准方法是使用一个事件。如果它们涉及整个类型而不仅仅是一个实例,那么它们可以是静态的。

首先定义一个EventArgs类:

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

    public int Index { get; private set; }
}

必须遵守其索引的类定义静态事件并在访问索引时触发它:

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));
        }
    }
}

想要观察此事件的对象,附上它:

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

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