2013-02-20 82 views
10

我正在使用MVC 4 Web API爲應用程序創建服務層。我正在嘗試創建一個全局篩選器,它將處理所有傳入API的請求。現在我明白,這必須與標準的MVC全局動作過濾器配置不同。但是,我遇到的問題是我在網上找到的任何示例工作。MVC 4 Web API註冊過濾器

我遇到的問題是使用Web API註冊過濾器。

我有我的Global.asax設立這樣的...

public class MvcApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     MVCConfig.RegisterRoutes(RouteTable.Routes); 
     MVCConfig.RegisterGlobalFilters(GlobalFilters.Filters); 

     WebApiConfig.RegisterRoutes(GlobalConfiguration.Configuration); 
     WebApiConfig.RegisterGlobalFilters(GlobalConfiguration.Configuration.Filters); 
    } 
} 

我的標準的MVC路由和過濾器正常工作。我的WebApi路由也一樣。以下是我爲我的WebAPI註冊過濾器...

public static void RegisterGlobalFilters(System.Web.Http.Filters.HttpFilterCollection filters) 
{ 
    filters.Add(new PerformanceTestFilter()); 
} 

這裏是PerformanceTestFilter ...當它與標準的MVC GlobalFilterCollection註冊

public class PerformanceTestFilter : ActionFilterAttribute 
{ 
    private readonly Stopwatch _stopWatch = new Stopwatch(); 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     _stopWatch.Reset(); 
     _stopWatch.Start(); 
    } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     _stopWatch.Stop(); 
     var executionTime = _stopWatch.ElapsedMilliseconds; 
     // Do something with the executionTime 
    } 
} 

該過濾器工作正常,但當我嘗試註冊它與System.Web.Http.Filters.HttpFilterCollection時,我得到一個錯誤,說它不能分配給參數類型System.Web.Http.Filters.IFilter。

所以我假設我的PerformanceTestFilter需要繼承ActionFilterAttribute以外的其他內容才能註冊爲webapi過濾器。我只是不確定需要什麼。

我想我需要創建兩個獨立的過濾器分別與mvc和webapi一起工作。如果有一種方法可以創建一個可以註冊到兩者的過濾器,那就太棒了。但我主要關心的只是讓它適用於webapi。

謝謝

回答

10

以下應該工作。我們實際上將其用於我們的Web API項目。

GlobalConfiguration.Configuration.Filters類型爲HttpFilterCollection

var filters = System.Web.Http.GlobalConfiguration.Configuration.Filters; 
filters.Clear(); 
filters.Add(new ValidationActionFilterAttribute()); 

public class ValidationActionFilterAttribute : FilterAttribute, IActionFilter, IFilter 
{ 
    ... 
} 

另外,如果你在同時包含MVC和的WebAPI assembilies一個項目時,你可以檢查有什麼命名空間的 ActionFilterAttribute的命名空間。這是相當混亂的原因有 正在兩個2個ActionFilterAttributes:

System.Web.Http.Filters 
    System.Web.Http.Mvc 

來源:Why is my ASP.NET Web API ActionFilterAttribute OnActionExecuting not firing?

看來,你將需要有兩個過濾器,一個用於API,一個用於MVC。您可以將通用代碼分解到單獨的類中,然後使用特定的過濾器來調用通用類,從而不違反DRY,並且實際上使用實際的過濾器作爲可以註冊爲過濾器的包裝器。

+3

好的,這個解決方案允許我的項目生成,我的過濾器被註冊到Web API的「System.Web.Http.Filters.HttpFilterCollection」以及標準MVC動作過濾的「GlobalFilterCollection」。但是,當我導航到其中一個API方法時,過濾器未被執行。該過濾器適用於標準的MVC控制器操作,但不適用於Web API方法。有什麼建議麼? – jdavis 2013-02-21 02:52:23

+0

提出新的問題。不要在評論中提出新問題。 – 2013-08-09 23:04:52

+1

@Sam,爲什麼在添加自己的過濾器之前清除過濾器集合? – Vegar 2014-02-04 12:10:51