Di mana dan bagaimana file layout _ViewStart.cshtml ditautkan?

199

Inilah About.cshtml dari templat MVC 3 default:

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

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

Saya berharap bahwa referensi ke file _ViewStart akan ditemukan di About.cshtml, tetapi jelas tidak.

Saya sudah melihat ke dalam global.asaxdanweb.config , tetapi saya tidak dapat menemukan bagaimana About.cshtmlfile "ditautkan" dengan tata letak dari file _ViewStart.

Semuanya berfungsi seperti yang diharapkan, saya hanya ingin tahu apa yang terjadi di bawah tenda ...

Kman
sumber

Jawaban:

237

Dari blog ScottGu :

Dimulai dengan rilis ASP.NET MVC 3 Beta, Anda sekarang dapat menambahkan file bernama _ViewStart.cshtml (atau _ViewStart.vbhtml untuk VB) di bawah folder \ Views proyek Anda:

File _ViewStart dapat digunakan untuk menentukan kode tampilan umum yang ingin Anda jalankan pada awal setiap rendering View. Sebagai contoh, kita bisa menulis kode di dalam file _ViewStart.cshtml kita untuk secara terprogram mengatur properti Layout untuk setiap View menjadi file SiteLayout.cshtml secara default:

Karena kode ini dijalankan pada awal setiap Tampilan, kami tidak perlu lagi mengatur Tata Letak secara eksplisit di file tampilan individual mana pun (kecuali jika kami ingin mengganti nilai default di atas).

Penting: Karena _ViewStart.cshtml memungkinkan kita untuk menulis kode, kita dapat membuat logika pilihan Layout lebih kaya daripada hanya set properti dasar. Sebagai contoh: kita dapat memvariasikan template Tata Letak yang kita gunakan tergantung pada jenis perangkat apa yang mengakses situs - dan memiliki tata letak ponsel atau tablet yang dioptimalkan untuk perangkat-perangkat itu, dan tata letak yang dioptimalkan desktop untuk PC / Laptop. Atau jika kami sedang membangun sistem CMS atau aplikasi bersama umum yang digunakan di banyak pelanggan, kami dapat memilih tata letak yang berbeda untuk digunakan tergantung pada pelanggan (atau peran mereka) ketika mengakses situs.

Ini memungkinkan banyak fleksibilitas UI. Ini juga memungkinkan Anda untuk lebih mudah menulis logika tampilan satu kali, dan menghindari pengulangan di banyak tempat.

Lihat juga ini .

jim tollan
sumber
14
Jadi ini lebih atau kurang fitur "hardcoded" dari MVC3? Saya tidak perlu mengubahnya ke halaman "default" lain, hanya ingin tahu bagaimana pengaturannya. Terima kasih telah menyortir semuanya :)
Kman
2
Kman- Hardcoded, dengan konvensi (pilih 'pegangan' lain di sini :)) - jadi ya, tepatnya. senang itu membersihkan kabut
jim tollan
Bukan hanya di folder "Tampilan" Anda yang mungkin Anda butuhkan. Jika Anda menambahkan RazorViewEngine khusus untuk mengatur tampilan ke folder lain, Anda juga harus memasukkan file ke dalam root folder tampilan alternatif tersebut. Sebagai contoh, saya memindahkan semua tampilan template Inspinia ke folder dan menjalankan ini di mesin tampilan ViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();. Akibatnya, saya harus menambahkan salinan file _ViewStart.cshtml saya ke "~ / Inspinia / ExampleViews", jika tidak diambil dan tata letak tidak ditetapkan.
Triynko
2
Jika folder Views Anda memiliki subfolder, dapatkah Anda menempatkannya _ViewStartdi setiap subfolder yang akan ditautkan ke tampilan dalam subfolder itu?
toddmo
35

Dalam pengertian yang lebih umum, kemampuan kerangka kerja MVC ini untuk "mengetahui" tentang _Viewstart.cshtml disebut "Pengodean dengan konvensi".

Convention over configuration (juga dikenal sebagai coding by convention) adalah paradigma desain perangkat lunak yang berupaya mengurangi jumlah keputusan yang perlu dibuat pengembang, mendapatkan kesederhanaan, tetapi tidak serta merta kehilangan fleksibilitas. Ungkapan tersebut pada dasarnya berarti pengembang hanya perlu menentukan aspek aplikasi yang tidak konvensional. Misalnya, jika ada Penjualan kelas dalam model, tabel terkait dalam database disebut "penjualan" secara default. Hanya jika seseorang menyimpang dari konvensi ini, seperti memanggil tabel "products_sold", orang perlu menulis kode mengenai nama-nama ini.

Wikipedia

Tidak ada keajaiban untuk itu. Ini baru saja ditulis ke dalam basis kode inti kerangka MVC dan karena itu sesuatu yang MVC "tahu" tentang. Itu sebabnya Anda tidak menemukannya di file .config atau di tempat lain; sebenarnya dalam kode MVC. Namun Anda dapat mengganti atau membatalkan konvensi ini.

rism
sumber
13
Jika MVC tahu tentang itu, lalu mengapa Visual Studio tidak tahu dan menunjukkan ini kepada saya? Jika pengkodean dengan konvensi berarti bahwa hal-hal bekerja selama Anda kebetulan tidak melanggar konvensi itu agak menyebalkan ...
Arne Evertsson
Tidak melanggar konvensi adalah intinya. AKAIK Ruby on Rails juga mengikuti paradigma ini.
Umar Farooq Khawaja
+1 Raif. Tidak ada gunanya membela "coding by convention" yang tidak didokumentasikan dengan buruk. Saya bisa mengatakan itu tentang salah satu kode mundur saya. "Apa? Kamu tidak mengira itu akan rusak ketika mencapai 33? Semua orang tahu kamu melewati 33." Sayangnya, celah dokumentasi untuk ASP.NET MVC sangat besar. Satu-satunya dokumen MS yang dibuat secara otomatis tanpa ringkasan sumber internal.
shannon
6
Konvensi konfigurasi tidak berarti Anda tidak dapat mengubahnya. HARUS ada konfigurasi yang tersedia untuk dapat menentukan nama dan lokasi file itu. Mungkin memang ada, tetapi siapa yang tahu apa itu. Orang-orang menggunakan mantra "konvensi atas konfigurasi" untuk mencakup banyak keputusan buruk dalam basis kode dan itu agak membuatku kesal sebagai orang yang mengikuti fakta untuk mempertahankan kekacauan yang tidak terdokumentasi dengan baik bahwa "hanya berfungsi" (tetapi Tuhan melarang Anda mengubah apa pun - Anda akan menghabiskan berjam-jam mencari tahu bagaimana Anda memecahkan segalanya).
Robert C. Barth
3
@AidenStrydom saya tidak setuju. Jawaban yang diterima sebenarnya memberi tahu saya cara menggunakan _ViewStart. Jawaban ini hanya berbicara tentang konsep desain. Saya datang ke sini untuk informasi tentang _ViewStart, bukan informasi tentang mengapa Visual Studio tidak akan memberi tahu saya apa pun tentang _ViewStart.
Millie Smith
23

Hanya pemikiran lain.

Jika Anda ingin memiliki milik Anda sendiri cshtml file sebagai templat umum, Anda dapat melakukannya dengan cara ini

Di dalam Anda, _viewstart.cshtmlAnda dapat menyebutkan cshtmlfile umum Anda .

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

Kode sumber adalah tempat yang jauh lebih baik untuk mencari ini daripada dokumentasi.

Referensi MVC 6 kode dari Github, kami memiliki beberapa file yang menarik

----memperbarui----

Karena perubahan struktur sumber, informasi tentang bagaimana halaman startstart dikumpulkan sekarang dapat ditemukan di RazorViewEngine.cs mencari fungsi "GetViewStartPages".

----/memperbarui----

Untuk menjawab bagaimana mereka berperan, lihat RazorView , yang saya percaya (karena IView) terkait dengan pipa MVC. File ini memiliki metode RenderAsync yang dipanggil dari pipa MVC untuk membuat tampilan yang diminta.

RenderAsync melakukan panggilan ke RenderPage DAN KEMUDIAN RenderLayout (CATATAN PESANAN). RenderPage pertama-tama melakukan panggilan untuk menangani file viewstart (perhatikan jamak, mungkin ada lebih dari satu file viewview).

Jadi, informasi yang Anda cari dapat diperoleh dari fungsi RenderViewStartAsync di file RazorView.cs di bawah Microsoft.AspNet.Mvc.Razor namespace.

Frison Alexander
sumber
7

Ini dapat menambahkan beberapa info tambahan ke pertanyaan ini sekarang (2016 ala MVC4, MVC5).

Mesin Razor menemukan dan menjalankan kode dalam _ViewStart.cshtml sebelum kode lain yang berada di direktori atau subdirektori yang sama di mana _ViewStart.cshtml ditemukan.

Tampilan apa pun dapat mengesampingkan properti Layout atau nilainya.

Hanya berpikir saya mungkin menambahkan sedikit lebih banyak info untuk menunjukkan kepada Anda mengapa _ViewStart.

Jika Anda mendapatkan ILSpy dan memeriksa kode di RazorViewEngine (System.Web.Mvc.dll), Anda akan melihat bahwa kode itu sendiri merujuk nama itu.

_Mulailah di System.Web.Mvc.dll

Anda dapat melihat bahwa RazorViewEngine mencari file dengan nama itu:

kode razorviewengine

RazorViewEngine.ViewStartFileName = "_ViewStart";
raddevus
sumber
3
ini yang saya cari, saya benci "tidak tahu" apa yang sedang terjadi di proyek saya, karena saya juga mengerjakan template sendiri untuk VS dan file yang baru saja keluar dari udara ini sangat tidak mudah dipahami
Sebastian 506563
1

Jika Anda ingin memiliki tata letak umum untuk halaman Anda, Anda perlu menentukan tata letak umum dan untuk mengaitkan tampilan dengan tata letak kita harus mengatur properti tata letak pada setiap tampilan, ini melanggar prinsip KERING (Jangan Ulangi Sendiri). Untuk .Net Framework ini telah menyediakan file "_ViewStart.cshtml", ditempatkan di dalam folder tampilan. Kami menempatkan informasi tata letak dalam file "_ViewStart.cshtml" dan setiap tampilan secara default menggunakan informasi tata letak ini. Jika Anda ingin memberikan beberapa informasi tata letak yang berbeda, anggaplah untuk tampilan Beranda Anda, Anda dapat membuat "_ViewStart.cshtml" baru dengan referensi tata letak itu dan meletakkannya di folder "Tampilan Rumah".

KamalDeep
sumber
1

Jawaban singkatnya adalah : ViewStart mulai lebih dulu ketika tampilan apa pun ditampilkan. Ceritanya di bawah ini:

Kisah pembuatan file tampilan tunggal:

  1. ViewStart digabung dengan ViewImports dan kemudian dieksekusi sebagai satu file. Perhatikan bahwa ViewImports selalu digabungkan dengan file cshtml apa pun termasuk file ViewStart. Tujuannya adalah untuk abstrak @ menggunakan pernyataan dan arahan umum lainnya.
  2. Output dari ViewStart (seperti Layout dan ViewData) menjadi tersedia untuk file View spesifik.
  3. Di dalam file View, jika variabel Layout adalah / menjadi null, isi tampilan diberikan dan hasil akhir dikirim ke pengguna.
  4. Jika variabel Layout adalah / menjadi bukan nol, eksekusi dipindahkan ke file tata letak yang pada gilirannya digabung dengan ViewImports sebagai file tunggal dan kemudian pada pernyataan @RenderBody () di dalam eksekusi file tata letak dipindahkan kembali ke file tampilan yang digabung dengan ViewImports lagi dan hasilnya digabung dengan file tata letak di lokasi @RenderBody () dan hasil akhirnya akhirnya dikirim ke pengguna.

Berharap ini membuat Anda menyadari apa yang sebenarnya terjadi di dalam misteri yang tidak diketahui dari siklus hidup program Anda.

Shadi Namrouti
sumber