Проверьте, находится ли атрибут на контроллере или действии

Когда срабатывает атрибут, могу ли я проверить, был ли он установлен на контроллере или действии?

Поведение, которое я хочу: используйте атрибут Action, если он существует, иначе используйте атрибут Controller. Что-то вроде этого:

public class TestAttribute : FilterAttribute, IAuthorizationFilter
{
    public TestAttribute(string optionalParam = "") { /*...*/ }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        bool isClassAttribute; // = ????

        bool hasActionAttribute = filterContext.ActionDescriptor.GetCustomAttributes(typeof(TestAttribute ), false).Length > 0;

        if (isClassAttribute && hasActionAttribute)
            return; // handle in Action attribute
        else
            ; // do stuff with optionalParam...
    }
}

[TestAttribute]
public class TestClass 
{    
    [TestAttribute(optionalParam:"foo"]
    public ActionResult TestMethod() { return null; }    
}

Я мог бы сделать это с помощью свойства Order, но не хочу устанавливать его каждый раз (или напугать).

Изменить/Решение

ОК, нашел решение моей проблемы (но не вопрос) - установка базового параметра атрибута AllowMultiple = false означает last instance of the same filter type is allowed, and all others are discarded (и атрибуты контроллера запускаются первыми (?), так что все должно быть хорошо...).

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class TestAttribute : FilterAttribute, IAuthorizationFilter
{
    public TestAttribute(string optionalParam = "") { /*...*/ }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        // this should be the Action attribute (if exists), else the Controller attribute...
    }
}

В любом случае, я задал немного другой вопрос, поэтому все равно буду давать баллы за ответ;)


person Seba Illingworth    schedule 02.04.2011    source источник


Ответы (1)


Я считаю, что элемент в любом случае выполняется при каждом вызове метода, но вы можете сослаться, например:

public void OnActionExecuting(ActionExecutingContext filterContext) { }
..
..

string controllerName = filterContext.Controller.GetType().Name;
//either or:
string actionMethodName = filterContext.ActionDescriptor.ActionName;
string actionMethodName = filterContext.RouteData.Values["action"].ToString();

Если ваше actionMethodName имеет значение null, то оно потенциально связано с вашим контроллером, хотя, как я уже сказал, они могут вызываться только тогда, когда метод действия вызывается как есть (не уверен на 100% в этом, хотя проверьте приведенный выше код, и он должен ответить на ваш вопрос)

Надеюсь, поможет : )

person Adam Tuliper - MSFT    schedule 03.04.2011
comment
Спасибо Адаму, но свойство ActionName существует и для атрибутов уровня контроллера. - person Seba Illingworth; 07.04.2011