ActionFilterAttribute для контроллера и метода действия

У меня есть LoggingAttribute, который регистрирует запрос и ответ в методе OnActionExecuted:

public class LoggingAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext httpContext)
    {
            //Logger.Log();
    }
}

Есть еще один атрибут для проверки запроса и возврата BadRequest. Этот ответ возврата из метода OnActionExecuting:

public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var modelState = actionContext.ModelState;
        if (!modelState.IsValid)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
        }
    }
}

Теперь, когда я применяю оба этих атрибута в методе Action, мои BadRequest не регистрируются, но когда я применяю LoggingAttribute на уровне контроллера и ValidateModelAttribute в методе действия, регистрируются BadRequests (вызывается OnActionExecuted из LoggingAttribute).

Может кто-нибудь объяснить это поведение, т.е. OnActionExecuted вызывается, даже если метод действия не выполняется, когда атрибут применяется к контроллеру.


person ctor    schedule 15.12.2017    source источник
comment
вы получаете точку останова на LoggingAttribute, когда применяете оба атрибута   -  person Pranay Rana    schedule 15.12.2017
comment
Если применяются оба метода действия — нет. Если LoggingAttribute на уровне контроллера и ValidateModetAttribute в методе действия — да.   -  person ctor    schedule 15.12.2017
comment
Вы пытались изменить последовательность метода действия?   -  person programtreasures    schedule 15.12.2017
comment
Вы добавили какой-либо глобальный фильтр?   -  person programtreasures    schedule 15.12.2017
comment
@programtreasures только что проверил, что это зависит от последовательности. если я сначала применяю LoggingAttribute, вызывается его OnActionExecuted. Пожалуйста, добавьте объяснение в ответ.   -  person ctor    schedule 15.12.2017
comment
привет, обновил мой ответ, вы можете посмотреть, что поможет ...   -  person Pranay Rana    schedule 15.12.2017


Ответы (2)


Сначала вам нужно применить LoggingAttribute к методу действия,

       [LoggingAttribute]
        [ValidateModelAttribute]        
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
person programtreasures    schedule 15.12.2017
comment
@programtreasures- извините, мой плохой, отменил мой голос, вы правы и +1 - person Pranay Rana; 15.12.2017

Я попробовал ваш сценарий, как показано ниже, на моем конце

[HttpGet]
[ValidateModelAttribute]
[LoggingAttribute]
public void test()
{
   //throw new NotImplementedException("This method is not implemented");
}

С тем же кодом, что и у вас, и я обнаружил ту же проблему, что и вы, ваш LogginAttribute не вызывается, потому что вы устанавливаете покой для контекста в своем ValidateModelAttribute, поскольку запрос получает ответ, он возвращается немедленно (из-за этого actionContext.Response =), поскольку запрос получил ответ, а затем он даже не вызывает метод, к которому вы применили атрибут.

Таким образом, решение для этой части состоит в том, что вам нужно написать OnActionExecuting, который вызывается перед вашим методом Validationattribute OnActionExecuting, и ваш код будет регистрироваться как метод OnActionExecuting LoggingAttribute до того, как вы вернете ответ.

public class LoggingAttribute : ActionFilterAttribute
{
   public override void OnActionExecuting
      (System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            //Logger.Log();
        }

   public override void OnActionExecuted(HttpActionExecutedContext httpContext)
        {
            //Logger.Log();
        }
}

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

[HttpGet]
[LoggingAttribute]
[ValidateModelAttribute]
public void test()
{
   //throw new NotImplementedException("This method is not implemented");
}

как предложено в ответе ниже от @programtreasures

person Pranay Rana    schedule 15.12.2017
comment
Этот атрибут не предназначен для регистрации исключений, он используется для регистрации всех запросов API. Кроме того, ответ не имеет отношения к вопросу. - person ctor; 15.12.2017
comment
OnActionExecuted из LoggingAttribute будет вызываться по описанному вами сценарию. Пожалуйста, перепроверьте это. - person ctor; 15.12.2017
comment
@PranayRana, когда модель недействительна и в ValidateModelAttribute настраивается ответ с неверным запросом, он все равно будет вызывать OnActionExecuted из LoggingAttribute, он не вернется немедленно, когда вы установите ответ в OnActionExecuting. Поправьте это, если я ошибаюсь. - person programtreasures; 15.12.2017