2015-02-06 45 views
6

我希望在ActionFilter中爲每個http請求創建一個對象並將這個對象傳遞給控制器​​。到目前爲止,我已經嘗試Request.Properties []像下面從ActionFilter.OnActionExecuting()傳遞一個對象到一個ApiController

public class DbReadonlyAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     actionContext.Request.Properties["CustomObjectKey"] = new MyClass(); 

而且我也試圖分配新對象定向到ControllerBase類。

public class DbReadonlyAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     var controller = (MyControllerBase) actionContext.ControllerContext.Controller; 
     controller.StorageContextFactory = new MyClass(); 

的問題是,無論是技術提供MyClass的的一個實例給控制器,因爲新的屬性[「CustomObjectKey」]在由被調用的控制器方法時的WebAPI管道丟失。

控制器在調用動作過濾器OnActionExecuting()之後由webapi管道重新實例化。

斷點確認Webapi管道在單個http請求期間調度以下事件流。

  • 構造MyControllerBase()
  • MyAuthenticationFilter
  • 過濾OnActionExecuting()
  • 構造MyControllerBase()
  • MyController.MethodA()

MyControler的雙實例是奇數,但現在我正在尋找任何技術將新創建的對象從操作過濾器傳遞到控制器。

編輯1:這個問題的v1中提到的MyAuthorizationFilter實際上是一個認證過濾器。仍在調查。

解決方案:該錯誤發生在另一個過濾器中。在我刪除我的認證過濾器後,在這個問題中報告的問題就消失了。

回答

13

您將不得不使用.add方法Request.Properties集合。

public class DbReadonlyAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     actionContext.Request.Properties.Add(new KeyValuePair<string, object>("CustomObjectKey", new MyClass())); 

您可以從您的api控制器中檢索這個值。

object _customObject= null; 

if (Request.Properties.TryGetValue("CustomObjectKey", out _customObjectKey)) 
{ 
    MyClass myObject = (MyClass)_customObject; 
} 
+0

謝謝您的輸入,我仍然將你的代碼改變後得到的問題,我現在懷疑我與異步鏈接一個更深層次的問題在我的驗證過濾器。 – camelCase 2015-02-06 13:54:14

+1

我一直在使用我粘貼在我的答案中的代碼。這對我來說可以。 – 2015-02-06 13:56:04

+0

我通過將我在WebApiConfig中聲明的全局認證過濾器移除爲config.Filters.Add(x)來簡化了這個問題;使用您的示例和我的原始屬性[「CustomObjectKey」] =技術從我的動作過濾器傳遞到控制器的對象適用於這兩個示例。我現在正在調查爲什麼我的身份驗證過濾器導致問題,例如雙控制器實例化。如果我解決了這個問題,我會回來並且讚揚你的回答,因爲你的建議讓我尋找更深層次的問題。 – camelCase 2015-02-06 14:15:39

0

另一種方式傳遞來自ActionFilter.OnActionExecuting()變量的ApiController:

public class CustomFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext actionContext) 
    { 
     actionContext.ControllerContext.RequestContext.RouteData.Values["CustomValue"] = "CustomValue"; 
    } 
} 

注意使用ActionFilterAttribute爲的Web API:

的System.Web。 Http.Filters.ActionFilterAttribute

MVC經典:

System.Web.Mvc。ActionFilterAttribute

使用:

[CustomFilter] 
public class SomeController : ApiController 
{ 
    string customValue = RequestContext.RouteData.Values.ToDictionary(x => x.Key, y => y.Value)["user_id"].ToString(); 
    //... 
} 
相關問題