2009-04-17 8 views
6

ユーザーが自分のアプリケーションにログインすると、アプリケーション全体に彼の名前が表示されます。私はasp.net MVCフレームワークを使用しています。C#MVCでVIewDataを繰り返すことを一元化する

ViewData["User"] = Session["User"]; 

これをあなた自身を繰り返さないことがあるので:しかし、私は何を望んでいないと、そのようにはすべてのコントローラ何かに配置する必要があるです。 (私はこれがDRY [OOプログラミングの原則を繰り返さない]と信じています) ViewData ["User"]は私のmasterpageにあります。ですから、私の質問は、私のViewData ["ユーザー"]を1か所で処理するためのきれいな方法は何ですか?

答えて

12

コントローラーのベースクラス、またはコントローラー/アクションに適用されているアクションフィルターのどちらでも簡単に実行できます。どちらの場合でも、アクションの前(または後)にリクエストに触れる機会が得られます。そこで、この機能を追加することができます。例えば

public class UserInfoAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(
     ActionExecutingContext filterContext) 
    { 
     base.OnActionExecuting(filterContext); 
     filterContext.Controller.ViewData["user"] = "Foo"; 
    } 
} 
... 
[HandleError, UserInfo] 
public class HomeController : Controller 
{...} 

アクション(方法)レベルでも使用することができる)


または共通のベースクラスで:

public abstract class ControllerBase : Controller 
{ 
    protected override void OnActionExecuting(
     ActionExecutingContext filterContext) 
    { 
     ViewData["user"] = "Bar"; 
     base.OnActionExecuting(filterContext); 
    } 
} 

[HandleError] 
public class HomeController : ControllerBase 
{...} 
+0

Thnx、私はベースクラスを試してみます。しかし、なぜOnActionExecuting()メソッドをオーバーライドするのですか?このメソッドは何をしますか?それは何の目的ですか? – Martijn

+0

アクション(メソッド)が実行される直前に実行されます。必要に応じて、OnActionExecutedを代わりに使用することもできます.OnActionExecutedは、アクションが実行された直後に実行されます。 –

+0

これは基本クラスに入れているので、コントローラー内での動作に影響しますか? – Martijn

2

UserNameプロパティを使用してモデルの基本クラスを作成します。

public abstract class ModelBase 
{ 
    public string UserName { get; set; } 
} 

コントローラ用の基本クラスを作成し、OnActionExecutedメソッドをオーバーライドします。モデル内でBaseModelからモデルが派生しているかどうかを確認し、そうであればUserNameプロパティを設定します。

public class ControllerBase : Controller 
{ 
    protected override void OnActionExecuted(
     ActionExecutedContext filterContext) 
    { 
     var modelBase = ViewData.Model as ModelBase; 

     if (modelBase != null) 
     { 
      modelBase.UserName = "foo"; 
     } 

     base.OnActionExecuted(filterContext); 
    } 
} 

次に、あなたは、このようなビューでは、ユーザーのユーザー名を表示することができます:

<%= Html.Encode(Model.UserName) %> 

参照:

+0

"モデルがBaseModelから派生しているかどうかをチェックし、"どうすればいいですか?あなたは私に例を挙げることができますか? – Martijn

+0

@Martijn、例を加えました。 –

+0

私はあなたの解決策を得ると思います。しかし、私はそれほど複雑ではありませんか? Marc Gravellの共通基盤クラスを同じようにしないでください。 – Martijn

5

それはされています年、私はちょうどアクロをつまんだこの質問に答えると良い答えがあると私は信じています。

ジミー・ボガードはアンチパターンとして受け入れ答えに記載された解決策を説明し、RenderActionを含む、より良いソリューションを提供しています:http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/18/the-filter-viewdata-anti-pattern.aspx

+0

リンクThnxの+1。 – Martijn

1
うち、アプリケーション全体を通じて持続的なモデルデータを提供するための別の方法はDefaultFactoryControllerとをオーバーライドすることである

あなたのカスタム1。 CustomerFactoryControllerでは、永続化したいモデルでViewBagを水和させます。

関連する問題