Apa yang saya lihat adalah properti Layout string. Tapi bagaimana saya bisa meneruskan model ke layout secara eksplisit?
c#
.net
asp.net-mvc
razor
SiberianGuy
sumber
sumber
Model
tersedia di_Layout
. Saya menggunakan MVC5.Jawaban:
Sepertinya Anda telah membuat model viewmodels Anda sedikit salah jika Anda mengalami masalah ini.
Secara pribadi saya tidak akan pernah mengetik halaman tata letak. Tetapi jika Anda ingin melakukannya, Anda harus memiliki model tampilan dasar yang diwarisi oleh model tampilan lain dan mengetik tata letak Anda ke model tampilan dasar dan halaman Anda ke model tampilan tertentu.
sumber
Contoh: Pengontrol:
Contoh bagian atas Halaman Tata Letak
Sekarang Anda dapat mereferensikan variabel 'viewModel' di halaman tata letak Anda dengan akses penuh ke objek yang diketik.
Saya menyukai pendekatan ini karena kontrolerlah yang mengontrol tata letak, sedangkan model tampilan halaman individual tetap agnostik tata letak.
Catatan untuk MVC Core
Mvc Core tampaknya menghilangkan konten ViewData / ViewBag saat memanggil setiap tindakan untuk pertama kalinya. Artinya, menetapkan ViewData di konstruktor tidak berfungsi. Apa yang berhasil, bagaimanapun, adalah menggunakan
IActionFilter
dan melakukan pekerjaan yang sama persis diOnActionExecuting
. MasukanMyActionFilter
pada AndaMyController
.sumber
ini adalah hal yang cukup mendasar, yang perlu Anda lakukan hanyalah membuat model tampilan dasar dan memastikan SEMUA! dan maksud saya SEMUA! dari tampilan Anda yang akan menggunakan tata letak itu akan menerima tampilan yang menggunakan model dasar itu!
di _Layout.cshtml:
dalam metode Indeks (misalnya) di pengontrol rumah:
Index.cshtml:
Saya tidak setuju bahwa meneruskan model ke _layout adalah kesalahan, beberapa info pengguna dapat diteruskan dan data dapat diisi dalam rantai pewarisan pengontrol sehingga hanya satu implementasi yang diperlukan.
jelas untuk tujuan yang lebih maju, Anda harus mempertimbangkan untuk membuat kontrol statis kustom menggunakan injeksi dan menyertakan namespace model itu di _Layout.cshtml.
tetapi untuk pengguna dasar ini akan berhasil
sumber
Solusi umum adalah membuat model tampilan dasar yang berisi properti yang digunakan dalam file layout dan kemudian mewarisi dari model dasar ke model yang digunakan di halaman masing-masing.
Masalah dengan pendekatan ini adalah bahwa Anda sekarang telah mengunci diri Anda sendiri ke dalam masalah model yang hanya dapat mewarisi dari satu kelas lain, dan mungkin solusi Anda sedemikian rupa sehingga Anda tidak dapat menggunakan pewarisan pada model yang Anda inginkan.
Solusi saya juga dimulai dengan model tampilan dasar:
Apa yang kemudian saya gunakan adalah versi umum dari LayoutModel yang diwarisi dari LayoutModel, seperti ini:
Dengan solusi ini saya telah memutuskan kebutuhan memiliki warisan antara model tata letak dan model.
Jadi sekarang saya bisa melanjutkan dan menggunakan LayoutModel di Layout.cshtml seperti ini:
Dan di halaman Anda dapat menggunakan LayoutModel generik seperti ini:
Dari pengontrol Anda, Anda cukup mengembalikan model tipe LayoutModel:
sumber
Mengapa Anda tidak menambahkan Partial View baru dengan kontroler spesifik milik saya yang meneruskan model yang diperlukan ke tampilan parsial dan akhirnya Render tampilan parsial yang disebutkan di Layout.cshtml Anda menggunakan RenderP Partial atau RenderAction?
Saya menggunakan metode ini untuk menampilkan info pengguna yang masuk seperti nama, gambar profil, dll.
sumber
pertanyaan lama tetapi hanya untuk menyebutkan solusi untuk pengembang MVC5, Anda dapat menggunakan
Model
properti yang sama seperti yang terlihat.The
Model
properti di kedua tampilan dan tata letak assosiated dengan samaViewDataDictionary
objek, sehingga Anda tidak harus melakukan kerja ekstra untuk melewati model Anda ke halaman tata letak, dan Anda tidak harus menyatakan@model MyModelName
dalam tata letak.Tetapi perhatikan bahwa ketika Anda menggunakan
@Model.XXX
dalam tata letak menu konteks intelliSense tidak akan muncul karena diModel
sini adalah objek dinamis sepertiViewBag
.sumber
Mungkin secara teknis ini bukan cara yang tepat untuk menanganinya, tetapi solusi paling sederhana dan paling masuk akal bagi saya adalah dengan membuat kelas dan membuat instance-nya dalam tata letak. Ini adalah pengecualian satu kali untuk cara melakukannya yang benar. Jika ini dilakukan lebih dari pada tata letak maka Anda perlu memikirkan kembali secara serius apa yang Anda lakukan dan mungkin membaca beberapa tutorial lagi sebelum melanjutkan lebih jauh dalam proyek Anda.
lalu dalam tampilan
di .net core Anda bahkan dapat melewati itu dan menggunakan injeksi ketergantungan.
Ini adalah salah satu area yang agak teduh. Tetapi mengingat alternatif yang sangat rumit yang saya lihat di sini, saya pikir itu lebih dari sekadar pengecualian yang baik untuk dibuat atas nama kepraktisan. Terutama jika Anda memastikan untuk membuatnya tetap sederhana dan memastikan logika yang berat (saya berpendapat bahwa sebenarnya tidak boleh ada, tetapi persyaratan berbeda) ada di kelas / lapisan lain di mana tempatnya. Hal ini tentunya lebih baik daripada mencemari SEMUA pengontrol atau model Anda hanya untuk satu tampilan ..
sumber
Ada cara lain untuk mengarsipkannya.
Cukup terapkan kelas BaseController untuk semua pengontrol .
Di
BaseController
kelas, buat metode yang mengembalikan kelas Model seperti misalnya.Layout
halaman Anda dapat memanggil metode ituGetTopMenu()
sumber
Anggaplah model Anda adalah kumpulan objek (atau mungkin satu objek). Untuk setiap objek dalam model, lakukan hal berikut.
1) Letakkan objek yang ingin Anda tampilkan di ViewBag. Sebagai contoh:
2) Tambahkan pernyataan using di bagian atas _Layout.cshtml yang berisi definisi kelas untuk objek Anda. Sebagai contoh:
@ menggunakan YourApplication.YourClasses;
3) Ketika Anda mereferensikan yourObject di _Layout cast itu. Anda dapat menerapkan pemeran karena apa yang Anda lakukan di (2).
sumber
Gunakan IContainsMyModel dalam tata letak Anda.
Terpecahkan. Aturan antarmuka.
sumber
Sebagai contoh
Baca selengkapnya tentang direktif @model baru
sumber