_ViewStart.cshtmlレイアウトファイルはどこにどのようにリンクされていますか?


199

デフォルトのMVC 3テンプレートのAbout.cshtmlは次のとおりです。

@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<p>
     Put content here.
</p>

_ViewStartファイルへの参照がで見つかると思いますがAbout.cshtml、明らかにありません。

私はで見てきたglobal.asaxweb.config、私はどのように見つけることができないAbout.cshtmlファイルが_ViewStartファイルからレイアウトを「連結」されています。

すべてが期待どおりに機能します。内部で何が行われているのか知りたいのですが...

回答:


237

ScottGuのブログから:

ASP.NET MVC 3 Betaリリース以降、プロジェクトの\ Viewsフォルダーの下に_ViewStart.cshtml(またはVBの場合は_ViewStart.vbhtml)というファイルを追加できるようになりました。

_ViewStartファイルを使用して、各ビューのレンダリングの開始時に実行する一般的なビューコードを定義できます。たとえば、_ViewStart.cshtmlファイル内にコードを記述して、各ビューのレイアウトプロパティをデフォルトでSiteLayout.cshtmlファイルに設定することができます。

このコードは各ビューの開始時に実行されるため、個々のビューファイルでレイアウトを明示的に設定する必要はありません(上記のデフォルト値をオーバーライドする場合を除く)。

重要:_ViewStart.cshtmlを使用してコードを記述できるため、オプションで、レイアウト選択ロジックを基本的なプロパティセットだけではなくより豊富にすることができます。たとえば、サイトにアクセスしているデバイスのタイプに応じて、使用するレイアウトテンプレートを変えることができます。これらのデバイスには、スマートフォンまたはタブレット向けに最適化されたレイアウトと、PC /ラップトップ向けにはデスクトップ向けに最適化されたレイアウトがあります。または、複数の顧客で使用されるCMSシステムまたは共通の共有アプリを構築している場合、サイトにアクセスするときに顧客(またはその役割)に応じて使用する異なるレイアウトを選択できます。

これにより、UIの柔軟性が大幅に向上します。また、ビューロジックをより簡単に記述し、複数の場所で繰り返すことを回避できます。

参照してくださいこれを


14
つまり、多かれ少なかれ、MVC3の「ハードコードされた」機能なのでしょうか。別の「デフォルト」ページに変更する必要はありません。設定方法に興味があります。すべてを整理していただきありがとうございます:)
Kman

2
Kman-慣例によりハードコードされています(ここで別の 'handle'を選択してください:))-そうです。霧が晴れて良かった
ジムトーラン

必要なのは「Views」フォルダだけではありません。ビューを他のフォルダーに整理するためにカスタムRazorViewEngineを追加する場合は、それらの代替ビューフォルダーのルートにもファイルを含める必要があります。たとえば、すべてのInspiniaテンプレートビューをフォルダに移動し、ビューエンジンで実行しましたViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();。その結果、_ViewStart.cshtmlファイルのコピーを「〜/ Inspinia / ExampleViews」に追加する必要がありました。追加しないと、ピックアップされず、レイアウトが設定されませんでした。
Triynko

2
Viewsフォルダーにサブフォルダーがある場合_ViewStart、そのサブフォルダーのビューにリンクするを各サブフォルダーに配置できますか?
toddmo

35

より一般的な意味で、MVCフレームワークが_Viewstart.cshtmlを「認識する」機能は、「規則によるコーディング」と呼ばれます。

構成上の規約(規約によるコーディングとも呼ばれます)は、開発者が行う必要のある決定の数を減らし、単純さを得るが必ずしも柔軟性を失うわけではないソフトウェア設計パラダイムです。このフレーズは本質的に、開発者がアプリケーションの型破りな側面を指定するだけでよいことを意味します。たとえば、モデルにクラスSaleがある場合、データベースの対応するテーブルはデフォルトで「sales」と呼ばれます。これらの名前に関するコードを記述する必要があるのは、テーブル「products_sold」の呼び出しなど、この規則から逸脱している場合のみです。

ウィキペディア

魔法はありません。これはMVCフレームワークのコアコードベースに書き込まれたばかりなので、MVCが「知っている」ものです。.configファイルや他の場所で見つからないのはそのためです。実際にはMVCコードに含まれています。ただし、これらの規則を変更または無効にするためにオーバーライドできます。


13
MVCがそれを知っている場合、なぜVisual Studioはこれを知らず、私にこれを指摘しないのですか?慣例によるコーディングが、慣習を破らない限りうまくいくことを意味する場合、それは一種の
厄介なこと

慣習を破らないことがポイントの一種です。AKAIK Ruby on Railsもこのパラダイムに従います。
Umar Farooq Khawaja 2013年

レイフ+1。文書化が不十分な「慣例によるコーディング」を擁護する意味はありません。私は私の後方コードのどれについてもそれを言うことができました。「何ですか?33になったときにクラッシュするとは思わなかったのですか。33をスキップしたことは誰もが知っています。」残念ながら、ASP.NET MVCのドキュメントのギャップは非常に大きいです。MSドキュメントのみが自動生成され、内部ソースサマリーはありません。
シャノン2014年

6
構成に関する規約は、それを変更できないという意味ではありません。そのファイルの名前と場所を指定できるようにするために利用可能な設定が必要です(SHOULD)。あるかもしれませんが、それが何であるか誰が知っています。人々は、「構成上の慣習」のマントラを使用して、コードベースでの多くの不適切な決定をカバーします。あなたが何かを変えることを神に禁ずる-あなたはすべてを壊した方法を理解するのに何時間も費やすでしょう)
ロバートC.バース2014

3
@AidenStrydom同意しない。受け入れられた答えは、実際に_ViewStartの使用方法を教えてくれます。この答えは、単に設計コンセプトについて話しているだけです。_ViewStartについての情報を得るためにここに来ました。VisualStudioが_ViewStartについて何も教えてくれない理由についての情報ではありません。
ミリー・スミス

23

ちょうど別の考え。

あなたが自分のものを持ちたいなら cshtmlファイルを共通のテンプレートとして使用する場合は、この方法で行うことができます

あなたの中であなた_viewstart.cshtmlはあなたの共通cshtmlファイルに言及することができます。

@{Layout = "~/Views/Shared/_Layout.cshtml";}

14

これを探すには、ドキュメントよりもソースコードの方がはるかに適しています。

GithubのMVC 6コードを参照すると、いくつかの重要なファイルがあります。

- - 更新 - -

ソース構造の変更により、viewstartページの収集方法に関する情報は、RazorViewEngine.csにあり、「GetViewStartPages」関数を探します。

- - /更新 - -

それらがどのように機能するかを回答するには、RazorViewを見てください。これは、(IViewのため)MVCパイプラインに関連付けられていると私は考えています。このファイルには、要求されたビューをレンダリングするためにMVCパイプラインから呼び出されるRenderAsyncメソッドがあります。

RenderAsyncは、RenderPageおよびTHEN RenderLayout(順序に注意)を呼び出します。RenderPageは、最初にビュースタートファイルを処理する呼び出しを行います(複数形に注意してください。複数の_viewstartファイルが存在する場合があります)。

したがって、求める情報は、Microsoft.AspNet.Mvc.Razor名前空間の下のRazorView.csファイルのRenderViewStartAsync関数から取得できます。


7

これにより、この質問にいくつかの追加情報が追加される可能性があります(2016 ala MVC4、MVC5)。

カミソリエンジン発見とのコード実行_ViewStart.cshtml同じディレクトリまたはサブディレクトリにある他のコードの前に_ViewStart.cshtmlが発見されています。

どのビューでもLayoutプロパティまたはその値を上書きできます。

なぜ_ViewStartなのかを示すために、もう少し情報を追加すると思いました。

ILSpyを取得し、RazorViewEngine(System.Web.Mvc.dll)のコードを調べると、コード自体がその名前を参照していることがわかります。

System.Web.Mvc.dllの_ViewStart

RazorViewEngineがその名前のファイルを探すことがわかります。

razorviewengineコード

RazorViewEngine.ViewStartFileName = "_ViewStart";

3
これは私が探していたものです。自分のプロジェクトで何が起こっているのか「わからない」が嫌いです。VSの独自のテンプレートも作成しているためです。このファイルは空気から出てきたもので、理解するのが非常に不便でした
Sebastian 506563

1

ページに共通のレイアウトが必要な場合は、共通のレイアウトを定義し、ビューをレイアウトに関連付けるために、すべてのビューにレイアウトプロパティを設定する必要があります。これは、DRY(Do n't Repeat Yourself)の原則に違反しています。このため、.Net Frameworkは、ビューフォルダー内に配置された「_ViewStart.cshtml」ファイルを提供しています。「_ViewStart.cshtml」ファイルにレイアウト情報を配置し、すべてのビューはデフォルトでこのレイアウト情報を使用します。いくつかの異なるレイアウト情報を提供したい場合は、ホームビューを想定して、そのレイアウトを参照して新しい「_ViewStart.cshtml」を作成し、「ホームビュー」フォルダーに配置します。


1

短い答えは次のとおりです。ビューがレンダリングされると、ViewStartsが最初に開始されます。長い話は以下の通りです:

単一のビューファイルの作成のストーリー:

  1. ViewStartはViewImportsとマージされ、単一のファイルとして実行されます。ViewImportsは、ViewStartファイルを含むcshtmlファイルと常にマージされることに注意してください。その目的は、@ usingステートメントおよびその他の一般的なディレクティブを抽象化することです。
  2. ViewStartの出力(LayoutやViewDataなど)は、特定のViewファイルで使用できるようになります。
  3. Viewファイル内で、Layout変数がnullになるかnullになると、ビューの本体がレンダリングされ、最終出力がユーザーに配信されます。
  4. Layout変数がnullでない場合はnullになると、実行はレイアウトファイルに移動され、次にViewImportsと1つのファイルとしてマージされ、レイアウトファイル内の@RenderBody()ステートメントで実行がビューファイルに戻されます。これは再びViewImportsとマージされ、出力は@RenderBody()の場所でレイアウトファイルとマージされ、最終的な出力は最終的にユーザーに配信されます。

これにより、プログラムのライフサイクルの未知の謎の中で実際に何が起こっているのかを理解できるようになることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.