2011-02-04 14 views
3

私はAsp.Net MVCフレームワークを使用してウェブサイトを開発しています。スタックオーバフローの最上部にあるレピュテーションバーと同様に、一般的なユーザー情報をいくつかのページに追加する必要があります。MVC - ビューに追加情報を渡す

この余分な情報をビューに追加するために、コントローラメソッドの作成にオーバーヘッドが追加されないようにすることが重要であると考えます。これはページの90%を越えて使用されている場合は

public ActionResult Index() 
{ 
    ViewData["reputationScore"] = GetUsersReputation(userId); 

    // main controller logic here 
} 

:これはViewDataを対象にこの情報を渡すか、それはすべてのコントローラはこのように見ていることになると評判のフィールドを受け入れるためのviewmodelsを修正するオプションを除外しますサイトでユーザーのバッジ数を表示したい場合は、変更するのにかなり時間がかかることがあります。

私はこの

使用マスターページに4つの解決策を考えることができます は、背後にあるマスターページのコード内のユーザーの評判を取得し、マスターページのマークアップで評判のためにマークを設置します。

短所:

  1. これは離れてMVCが表すすべてのものから移動しているようです。
  2. 代替ビューエンジン(例:剃刀など)の使用に移行することを検討していますが、これらがどの程度うまく混合するかはわかりません。
  3. 評判のレイアウトを制限する傾向があります。ページの中央に配置するのは難しいです。

GetUsersReputationメソッドを追加するためのHtmlHelperの拡張 これは、HTMLオブジェクトがために使用されるべきもののわずかな違反であると思われる - それだけで出力をレンダリングするが、データベースをヒットされていません。私は、この比喩の違反以外の他の重大な問題は考えられません。

上書きSystem.Web.Mvc.ViewPage オーバーライドビューページには、データベースにアクセスする方法の選択を呼び出すために使用することができるHTMLに加えて、オブジェクトを露出させます。拡張メソッドをHtmlHelperと同じ方法で追加できるようにして、新しいメソッドが必要なときに、それが適切に拡張できるようにします。これは、私たちはのようなものを書くことができる可能性があり:

<% DataAccess.GetUsersReputation() %> 

すべてのメソッドあなたを保持することができ、ベースビューモデルでそれをラップし、むしろストレートビューにビューモデルを渡すよりも、ベース汎用ビューモデル を作成します。必要があります:

public ActionResult Index() 
{ 
    MyViewModel viewCoreInfo = model.GetData(); 

    return View(new BaseViewModel<MyViewModel>(viewCoreInfo)); 
} 

BaseViewModelは、Webページに必要な追加情報に必要なすべてのプロパティを公開することができます。例えばUsersReputation(コンストラクタでデータベースにクエリを実行するか、プロパティにアクセスするときにデータを読み込む)私はこれがMVCのメタファーをより良く維持すると思いますが、ちょっと面倒です。

  1. 他の誰かが最善であるよりよい解決策
  2. を打ち出している - あなたは、彼らが問題/効果的であったそれらを使用している場合は?

答えて

3

あなたはかみそりビューエンジンへの移行の可能性を言及しているので、私はScottGuによってTHISブログ記事に関心があるかもしれないと思います。

彼は、あなたのレイアウト(「マスターページ」)に追加コンテンツを読み込むことができるセクションを作成するために必要な、剃刀で 'セクション'を使用して説明します。このようにSOスタイル情報バーを作成すると、きれいでシンプルになります。

EDIT:限り以下のコメントにつき、部分ビューをレンダリングするよう

...新しいmvc music store tutorialはいくつかの例があります。

この場合、Html.RenderActionを使用しています。 Html.RenderPartialは別のオプションです。 この相違点はquestionですが、ネット上に他のリソースがあることは確かです。

あなたのコントローラは、ちょうどのような部分的なビューを返します:あなたはデータと部分図を移入ます分離コードファイルとの部分図を作成することができます

return PartialView(); 
+0

セクションはWebformsエンジンのContentPlaceHoldersと同じです。 OPが持っている問題を本当に解決するものではありません。 OPは、どのように情報がビュー/セクション/コントローラに転送されるべきであるものに置かれるのかと不思議に思っています。 – jgauffin

+0

答えをありがとう。これは、カミソリはマスターページでマークアップを作成することはできますが、一般的には、表示ロジック以外のビューにコードを書くことは悪い習慣と考えられますが、同じ問題が残っていると思います。確かにデータアクセスメソッドを置く場所ではありません。これは実際にはモデル/コントローラの責任です。しかし、重複を避けるために、私はすべてのコントローラで評判メソッドを呼び出す必要がないようにしたいと考えています。 –

+0

@Giles私はあなたが何を意味するかを見ます。セクションが独自のコントローラ/アクションまたはこれらの行に沿ったものを呼び出す部分ビューをレンダリングする場合はどうなりますか? – stephen776

0

私はこれを行い、すべての情報を共通にしたベースモデルクラスを作成しました。私の他のすべてのビューモデルクラスはこのクラスから継承します。しかし、各コントローラにこれらの情報を入力する必要があります。これは私が選んだ解決策です。

3

MyViewModelが継承するのはなぜですかBaseViewModel

ザ・あなたが共通の価値観を埋めるためにBaseController.OnResultExecutingを使用することができます。

protected override void OnResultExecuting(ResultExecutingContext ctx) { 
    base.OnResultExecuting(ctx); 
    var baseView = ctx.Result as BaseViewModel; 
    if (baseView != null) 
    { 
     //assign values here 
    } 
} 
+0

感謝を。私はOnResultExecutingメソッドをオーバーライドするのが好きです。私の心配は、MyViewModelにBaseViewModelを継承させることになり、2つのクラス間の結合を導入することになります。後で別のページグループで友人数を表示する必要があるのに、メインデータ用にMyViewModelを使用している場合は、BaseViewModelに友人と評判の両方のメソッドを含める必要があります。私のソリューションでは、FriendDataBaseViewModelのBaseViewModelを変更するだけです。あなたの助けていただきありがとうございます - 今OnResultExecutingを調べます。 –

+0

'IMasterPageData'などのインターフェースを作成します。あなたの 'BaseViewModel'と' FriendDataBaseViewModel'はそれを実装しましょう。それから、代わりに 'OnResultExecuting'のチェックを' IMasterPageData'に変更してください。 – jgauffin

0

。それは少し非MVCの方法ですが、それは動作します。

1

あなたは、アクションフィルタを作成OnResultExecutingをオーバーライドし、共通の値を記入してくださいあなたのアクション/コントローラに追加することができます:答えのための

public class AddCommonData : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
    ViewResult viewResult = filterContext.Result as ViewResult; 
    if (viewResult != null) 
    { 
     //... 
    } 
    } 
} 
関連する問題