簡體   English   中英

控制器上的ActionFilterAttribute與操作方法

[英]ActionFilterAttribute on Controller vs action method

我有一個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應用於操作方法時,則會記錄BadRequest (調用LoggingAttribute OnActionExecuted )。

有人可以解釋這種行為嗎,即當在控制器上應用屬性時,即使未執行動作方法,也會調用OnActionExecuted

您需要先在操作方法上應用LoggingAttribute

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

我嘗試了如下情況

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

使用與您相同的代碼,並且發現與您相同的問題,未調用LogginAttribute因為您在ValidateModelAttribute為上下文設置了LogginAttribute ,因為請求獲取響應它會立即返回(因為此actionContext.Response = ),因為請求獲取了響應,然后它甚至不調用您應用了屬性的方法。

因此,這部分的解決方案是您必須編寫OnActionExecuting ,該方法在Validationattribute OnActionExecuting方法之前被調用,並且您的代碼將在返回響應之前作為LoggingAttribute 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();
        }
}

並且還更改了order或attribute,下面這樣做的原因是當設置了Response時,在這種情況下,它僅從該點返回,因此,在管道中的任何過濾器都不會被調用。

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

如@programtreasures在以下答案中所建議

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM