4

ユーザーがログインしているかどうかを確認し、ユーザーIDを取得する単純なアクションフィルターを使用します。C#MVCのActionFilterからController Actionに変数を渡すにはどうすればよいですか?

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int id = Authentication.SomeMethod(); 
     // Pass the ID through to the controller? 
     ..... 
    } 
} 

このIDをコントローラアクションに渡す方法はありますか?

[LoginFilter] 
public class Dashboard : Controller 
{ 
    public ActionResult Index() 
    { 
     // I'd like to be able to use the ID from the LoginFilter here 
     int id = .... 
    } 
} 

私にこれを可能にするViewBagに相当するものはありますか?あるいは、フィルタとコントローラアクションの間で変数やオブジェクトを渡すことを可能にする他の技術ですか?

答えて

5

あなたのような他のほとんどの標準的なデータを取得するためにIdとプロパティを取得するための拡張メソッドを持っているController.Userを使用することができますこのようViewData/ViewBagを使用することができます。

1.)ViewData

使用注:をViewDataをする場合は、あなたがTYPする必要がある一歩を行う必要がありますecastそれ

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int idValue = Authentication.SomeMethod(); 

     // Pass the ID through to the controller? 
     filterContext.Controller.ViewData.Add("Id", idValue); 
    } 
} 

そしてコントローラ機能で

[LoginFilter] 
public class Dashboard : Controller 
{ 
    public ActionResult Index() 
    { 
     // I'd like to be able to use the ID from the LoginFilter here 
     int id = (int)ViewData["Id"]; 
    } 
} 

2)ViewBag

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int idValue = Authentication.SomeMethod(); 

     // Pass the ID through to the controller? 

     filterContext.Controller.ViewBag.Id = idValue; 
    } 
} 

を使用して、コントローラ

[LoginFilter] 
public class Dashboard : Controller 
{ 
    public ActionResult Index() 
    { 
     // I'd like to be able to use the ID from the LoginFilter here 
     int id = ViewBag.Id; 
    } 
} 
+0

おかげさまで、私はViewbagではなく、@ luisoの回答として提案されたTempDataを使用してしまいました。 ViewDataを使用すると、実際の使用方法と例がわかり、テクニックはTempDataの場合と同じです。これは、ビュー用のものではなく、これが一時データであることが分かります。したがって、TempData –

4

ActionExecutingContextには、呼び出し側のコントローラへの参照が含まれていると思います。これを基底のControllerクラスから派生したカスタムコントローラクラスと混在させて使用すると、コントローラのインスタンス変数としてidを格納することになります。

カスタムコントローラ

Public Class MyController : Controller 
{ 
    Public int Id {get;set;} 
} 

LoginFilter

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int id = Authentication.SomeMethod(); 
     ((MyController)filterContext.Controller).Id = id; 
     //Assign the Id by casting the controller (you might want to add a if ... is MyController before casting) 
    } 
} 

コントローラ

[LoginFilter] 
public class Dashboard : MyController 
{ 
    public ActionResult Index() 
    { 
     //Read the Id here 
     int id = this.Id 
    } 
} 
+0

に私はこのソリューションの論理が好き、それは直接IDを植えるという点で実際に実装されている人はあとでコードを保持する人にとっては少し不透明だと思われるので、IDはちょうど魔法のように説明せずに設定されているようです。 –

+0

公正な批評、ありがとう –

6

次の操作を行うことによりViewBagを使用することができます。

filterContext.Controller.ViewBag.Id = id; 

これを行う必要があります。filterContext.Controllerを入力すると、その中のすべてのフィールドにはTempDataのようにアクセスできます。あなたはおそらく、ユーザーのIDを取得し、その後OWINを使用している場合

はそうであっても、あなたはNameなど

+0

ええと、これはきちんとした解決策のようです。論理的には、おそらくViewBagを使用することは意味がありませんが、TempDataはおそらくそれには適しています。私はOWINを使用していません(少なくとも、認証技術を混ぜているので、プロジェクトのこの部分ではありません) –

関連する問題