ASP.NET MVCのマスターページにデータを渡す


102

MVCルールに違反せずに(ASP.NET MVCを使用して)マスターページにデータを渡す方法は何ですか?

個人的には、すべてのビューに渡される抽象コントローラー(基本コントローラー)または基本クラスをコーディングすることを好みます。


1
私はこれをどのように管理したかについてガイドを書きました:britishdeveloper.co.uk/2010/06/…役立つはずです
BritishDeveloper

回答:


77

ビューが強く型付けされたビューデータクラスを持つことを好む場合、これはうまくいくかもしれません。他の解決策はおそらくより正確ですが、これはデザインと実用性の間の素晴らしいバランスです。

マスターページは、それに関連する情報のみを含む強く型付けされたビューデータクラスを取ります。

public class MasterViewData
{
    public ICollection<string> Navigation { get; set; }
}

そのマスターページを使用する各ビューは、その情報を含み、マスターページのビューデータから派生した、強く型付けされたビューデータクラスを受け取ります。

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
}

個々のコントローラーがマスターページデータをまとめることについて何も知りたくないので、そのロジックをファクトリーにカプセル化して、各コントローラーに渡します。

public interface IViewDataFactory
{
    T Create<T>()
        where T : MasterViewData, new()
}

public class ProductController : Controller
{
    public ProductController(IViewDataFactory viewDataFactory)
    ...

    public ActionResult Index()
    {
        var viewData = viewDataFactory.Create<ProductViewData>();

        viewData.Name = "My product";
        viewData.Price = 9.95;

        return View("Index", viewData);
    }
}

継承はマスターとビューの関係をうまく一致させますが、パーシャル/ユーザーコントロールのレンダリングに関しては、ビューデータをページビューデータに構成します。

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
    public SubViewData SubViewData { get; set; }
}

<% Html.RenderPartial("Sub", Model.SubViewData); %>

これはコード例であり、そのままコンパイルすることを意図したものではありません。ASP.Net MVC 1.0用に設計されています。


4
これはスコットガストリーが推奨する方法なので、同意する必要があります。
Simon Fox

@Simon Fox-scottguの推奨へのリンクを取得しましたか?見つかりませんでした。
orip 09


ごめんなさい。これの一部を理解するのに少し問題があります。コントローラーのコンストラクターにはIViewDataFactoryのインスタンスが渡されますが、システムはパラメーターのないコンストラクターを想定しています。インターフェイスのC#構文(特に "MasterViewData、new()")についてもよく知りません。誰かがそれを説明したり、優れたリソースを私に指摘したりできますか?ありがとう。
ジェイソン

5
強く型付けされたモデルを操作するのが好きですが、マスターデータを他のすべてのモデルやアクションと組み合わせるのはあまり好きではありません。少し遅れてこのスレッドに飛び込んできましたが、状況をより緩やかに保つマスターデータへのアプローチを投稿しました。
Todd

59

マスタービューのデータ駆動型の部分をパーシャルに分割し、Html.RenderActionを使用してレンダリングすることを好みます。これには、一般的なビューモデル継承アプローチに比べていくつかの明確な利点があります。

  1. マスタービューデータは、「通常の」ビューモデルから完全に切り離されています。これは継承に対する構成であり、変更が容易な疎結合システムになります。
  2. マスタービューモデルは、完全に別のコントローラーアクションによって構築されます。「通常の」アクションはこれを心配する必要はありません。また、私のデータでは過度に複雑に見えるビューデータファクトリは必要ありません。
  3. AutoMapperなどのツールを使用してドメインをビューモデルにマッピングした場合、マスタービューデータを継承しない場合、ビューモデルはドメインモデルによく似ているため、設定が簡単になります。
  4. マスターデータに個別のアクションメソッドを使用すると、ページの特定の領域に出力キャッシュを簡単に適用できます。通常、マスタービューには、メインページのコンテンツよりも変更頻度が少ないデータが含まれています。

3
+1。別の利点は、現在のランタイム状態に応じて、同じビューで異なるマスターページを使用できることです。
StriplingWarrior

1
私はこの答えがとても好きです-概説されている他のアプローチは少し複雑に見えます。
Paddy

2
これは私の意見では最もエレガントなソリューションです。
autonomatt 2011年

1
この解決策は私にとっても最良のようです。どうもありがとう!
ジムダニエル、2011年

1
これは素晴らしい方法ですが、「部分的なアクション」へのルートを指定する必要があることを忘れないでください。この回答を参照してください。stackoverflow.com/a/3553617/56621
Alex

20

編集する

Generic Errorは、以下のより良い答えを提供しています。読んでください!

元の回答

マイクロソフトは実際にこれを処理するための「公式」な方法でエントリーを投稿しました。これは、彼らの推論の説明とともに段階的なウォークスルーを提供します。

つまり、抽象コントローラークラスを使用することをお勧めしますが、自分で確認してください。


ありがとうございました!その例は、データベースから取得したすべてのページのカテゴリです。
マーティン

MVCの作者の1人であるスコットガスリーは、以下の@Generic Errorが提供する解決策を推奨します
Simon Fox

1
+1は、あなたの回答が公式に正しく、OPによって回答として受け入れられた場合でも、最良の回答に導くために使用します。
IsmailS 2011年

+1は、あなたの回答が公式に正しく、OPによって回答として受け入れられた場合でも、最良の回答に導くために使用します。
Dave Jellison、2011

実際には、トッド・メニアーズがこれに対する最良の答えです。
andreialecu 2009

7

コントローラーを抽象化するのは良い考えであり、私にはこれ以上の方法はありません。他の人たちも何をしたか見てみたいです。



2

ビューに渡すすべてのモデルオブジェクトの共通の親が非常に役立つことがわかりました。

いずれにしても、ページ間で常にいくつかの共通のモデルプロパティが存在する傾向があります。


0

Request.Paramsオブジェクトは変更可能です。要求処理サイクルの一部としてスカラー値を追加するのは非常に簡単です。ビューの観点からは、その情報はQueryStringまたはFORM POSTで提供されている可能性があります。hth


0

別の良い方法は、いくつかのインターフェイスのParentViewのようなプロパティを持つビューのインターフェイスを作成することです。そのため、ページ(親コントロール)への参照を必要とするコントロールと、そこからアクセスする必要のあるマスタービューの両方に使用できます。ビュー。


0

他のソリューションは優雅さに欠け、時間がかかりすぎます。ほぼ1年後、この非常に悲しくて貧困なことをしてしまったことをお詫びします。

<script runat="server" type="text/C#">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        MasterModel = SiteMasterViewData.Get(this.Context);
    }

    protected SiteMasterViewData MasterModel;
</script>

したがって、SiteMasterViewDataを返すSiteMasterViewDataにこの静的メソッドGet()があることは明らかです。


多くの場合、これは少しハックや「汚れ」に見えるかもしれないが、それは仕事が早くpreetyを行って取得します
なんてこった

ああ。Html.RenderAction()を使用した場合、コードを維持するのがはるかに難しくなります。
Dan Esparza
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.