【问题标题】:ActionFilterAttribute on Controller vs action method控制器上的 ActionFilterAttribute 与操作方法
【发布时间】:2017-12-15 05:56:05
【问题描述】:

我有一个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 方法上应用这两个属性时,我的 BadRequests 没有被记录,但是当我在控制器级别应用 LoggingAttribute 和在操作方法上应用 ValidateModelAttribute 时,BadRequests 正在被记录( OnActionExecutedLoggingAttribute 被调用)。

有人可以解释一下这种行为,即OnActionExecuted 被调用,即使在控制器上应用属性时未执行操作方法。

【问题讨论】:

  • 当您同时应用这两个属性时,您是否在 LoggingAttribute 上获得断点
  • 如果同时在 actionmethod 上应用 - 否。如果 LoggingAttribute 在控制器级别,ValidateModetAttribute 在 action 方法上 - 是。
  • 您是否尝试过更改 action 方法的顺序?
  • 你添加了全局过滤器吗?
  • @programtreasures 刚刚检查它是否依赖于序列。如果我首先应用 LoggingAttribute,它的 OnActionExecuted 就会被调用。请在答案中添加解释。

标签: c# asp.net asp.net-web-api action-filter actionfilterattribute


【解决方案1】:

你需要先在action方法上申请LoggingAttribute

       [LoggingAttribute]
        [ValidateModelAttribute]        
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

【讨论】:

  • @programtreasures- 对不起,我的错,回复我的投票,你是正确的,+1
【解决方案2】:

我在最后尝试了如下所示的场景

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

使用与您相同的代码,我发现与您相同的问题,您的 LogginAttribute 没有被调用,因为您在 ValidateModelAttribute 中为上下文设置了休止符,因为请求得到响应它立即返回(因为这个 @987654324 @ ) 作为请求得到响应,然后它甚至不调用你应用属性的方法。

因此,这部分的解决方案是您必须编写OnActionExecuting,它在您的Validationattribute OnActionExecuting 方法之前被调用,并且您的代码将在您返回响应之前记录为LoggingAttributeOnActionExecuting 方法。

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 在下面的回答中所建议的那样

【讨论】:

  • 该属性不用于异常记录,它用于记录一个API的所有请求。此外,答案与问题无关。
  • OnActionExecuted of LoggingAttribute 将在您提到的场景中被调用。请重新检查。
  • @PranayRana 当模型无效并且在ValidateModelAttribute 设置响应时请求错误仍然会调用LoggingAttributeOnActionExecuted,当您在OnActionExecuting 中设置响应时它不会立即返回.如果我错了,请更正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多