Фильтры действий на контроллере, но используются только в том случае, если к методу применяется другой ([HttpPost])?

Я хотел бы применить фильтр на уровне контроллера, но его логика применяется только к методам действий, на которых непосредственно установлен фильтр [HttpPost].

Возможно, внутри одного фильтра можно определить, был ли применен другой фильтр к текущему методу действия?

Или есть другой способ добиться эффекта, который я описал в первом предложении? Возможно, есть способ расширить или заменить HttpFilter?


person Faust    schedule 03.12.2011    source источник


Ответы (2)


Я думаю, это то, что вы ищете:

public class PostActiongFilter : ActionFilterAttribute
{
    public virtual void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var actionName = filterContext.ActionDescriptor.ActionName;
        var actionParams = filterContext.ActionDescriptor.GetParameters
        var actionParamsTypes = actionParams.Cast<ParameterDescriptor>()
                                      .Select(x => x.ParameterType).ToArray();
        var controllerType = filterContext.Controller.GetType();            
        var actionMethodInfo = controllerType.GetMethod(actionName,
                                                        actionParamsTypes, null);            
        var isMethodPost = actionMethodInfo.IsDefiend(typeof(HttpPostAttribute),
                                                      false);

        if (!isMethodPost)
            return;

        // Do what you want for post here...                         
    }
}
person gdoron is supporting Monica    schedule 03.12.2011
comment
Исправление в вашей последней строке: var isMethodPost = actionMethodInfo.IsDefined(typeof(HttpPostAttribute), false); - person Ryk; 30.08.2013
comment
@Рик, спасибо. Кстати, этот сайт позволяет вам редактировать\предлагать изменения, когда вы хотите. в любом случае спасибо, ты попал в точку. - person gdoron is supporting Monica; 30.08.2013

Хорошо, HttpPostAttribute запечатан. Но вы можете заглянуть в него (ваш друг ILSpy) для вдохновения:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class HttpPostAttribute : ActionMethodSelectorAttribute
{
    private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        return HttpPostAttribute._innerAttribute.IsValidForRequest(controllerContext, methodInfo);
    }
}

довольно просто да? Вы просто создаете точно такую ​​же логику, а взамен ставите

return (yourCustomCondition) && HttpPostAttribute._innerAttribute.IsValidForRequest(controllerContext, methodInfo);
person rouen    schedule 03.12.2011
comment
Этот ответ на самом деле не является общим решением, поскольку внутренняя логика атрибута HttpPost может быть изменена в более высокой версии MVC, и тогда это решение перестанет работать. В этом случае ответ, предоставленный @gdoron, намного лучше. - person Anton; 20.01.2016