Saya memiliki situs web yang memiliki halaman tata letak. Namun halaman tata letak ini memiliki data yang semua model halaman harus memberikan judul halaman, nama halaman dan lokasi di mana kita sebenarnya untuk pembantu HTML yang saya lakukan yang melakukan beberapa tindakan. Juga setiap halaman memiliki properti model tampilan mereka sendiri.
Bagaimana saya bisa melakukan ini? Tampaknya itu ide yang buruk untuk mengetik tata letak tapi bagaimana cara menyampaikan info ini?
asp.net-mvc-4
Rushino
sumber
sumber
ViewBag
. Mungkin masalah preferensi. Memberikan suara positif pada komentar AndaJawaban:
Jika Anda diminta untuk meneruskan properti yang sama ke setiap halaman, maka membuat model tampilan dasar yang digunakan oleh semua model tampilan Anda akan bijaksana. Halaman tata letak Anda kemudian dapat menggunakan model dasar ini.
Jika ada logika yang diperlukan di balik data ini, maka ini harus dimasukkan ke dalam pengontrol dasar yang digunakan oleh semua pengontrol Anda.
Ada banyak hal yang dapat Anda lakukan, pendekatan yang penting adalah tidak mengulangi kode yang sama di banyak tempat.
Edit: Perbarui dari komentar di bawah
Berikut adalah contoh sederhana untuk mendemonstrasikan konsep tersebut.
Buat model tampilan dasar yang akan mewarisi semua model tampilan.
Halaman tata letak Anda dapat menganggap ini sebagai modelnya.
Terakhir, atur data dalam metode tindakan.
sumber
public class HomeController : BaseController
. Dengan cara ini kode umum hanya perlu ditulis sekali dan dapat diterapkan ke semua pengontrol.Saya menggunakan pembantu html RenderAction untuk pisau cukur dalam tata letak.
Saya membutuhkannya untuk string sederhana. Jadi tindakan saya mengembalikan string dan menuliskannya dengan mudah. Tetapi jika Anda membutuhkan data yang kompleks, Anda dapat mengembalikan PartialViewResult dan model.
Anda hanya perlu meletakkan model Anda di awal tampilan parsial '_maP PartialView.cshtml' yang Anda buat
Kemudian Anda dapat menggunakan data dalam model dalam tampilan parsial itu dengan html.
sumber
Pilihan lainnya adalah membuat kelas LayoutModel terpisah dengan semua properti yang Anda perlukan dalam layout, dan kemudian memasukkan instance kelas ini ke dalam ViewBag. Saya menggunakan metode Controller.OnActionExecuting untuk mengisinya. Kemudian, di awal tata letak, Anda dapat menarik objek ini kembali dari ViewBag dan terus mengakses objek yang sangat diketik ini.
sumber
OnActionExecuting
. Menggunakan ViewBag juga berarti Anda kehilangan keamanan jenis pada pengontrol Anda, bukan hal yang baik.Agaknya, kasus penggunaan utama untuk ini adalah mendapatkan model dasar ke tampilan untuk semua (atau sebagian besar) tindakan pengontrol.
Mengingat itu, saya telah menggunakan kombinasi dari beberapa jawaban ini, dukungan piggy utama pada jawaban Colin Bacon.
Benar bahwa ini masih logika pengontrol karena kita sedang mengisi model tampilan untuk kembali ke tampilan. Jadi tempat yang tepat untuk meletakkan ini adalah di pengontrol.
Kami ingin ini terjadi pada semua pengontrol karena kami menggunakan ini untuk halaman tata letak. Saya menggunakannya untuk tampilan parsial yang dirender di halaman tata letak.
Kami juga masih menginginkan manfaat tambahan dari ViewModel yang diketik dengan kuat
Jadi, saya telah membuat BaseViewModel dan BaseController. Semua Pengontrol ViewModels masing-masing akan mewarisi dari BaseViewModel dan BaseController.
Kode:
BaseController
Perhatikan penggunaan OnActionExecuted seperti yang diambil dari posting SO ini
HomeController
BaseViewModel
HomeViewModel
FooterModel
Layout.cshtml
_Nav.cshtml
Semoga ini membantu.
sumber
Anda tidak perlu mengacaukan tindakan atau mengubah model, cukup gunakan pengontrol dasar dan transmisikan pengontrol yang ada dari tata letak konteks tampilan.
Buat pengontrol dasar dengan data umum yang diinginkan (judul / halaman / lokasi dll) dan inisialisasi tindakan ...
Pastikan setiap pengontrol menggunakan pengontrol dasar ...
Transmisikan pengontrol dasar yang ada dari konteks tampilan di
_Layout.cshml
halaman Anda ...Sekarang Anda dapat merujuk ke nilai-nilai di pengontrol dasar dari halaman tata letak Anda.
MEMPERBARUI
Anda juga dapat membuat ekstensi halaman yang memungkinkan Anda untuk menggunakannya
this
.Maka Anda hanya perlu mengingat untuk menggunakan
this.Controller()
saat Anda menginginkan pengontrol.atau pengontrol khusus yang mewarisi dari
_BaseController
...sumber
jika Anda ingin meneruskan seluruh model, lakukan seperti di layout:
dan tambahkan ini di pengontrol:
sumber
Saya rasa tidak ada jawaban yang cukup fleksibel untuk aplikasi tingkat perusahaan besar. Saya bukan penggemar terlalu banyak menggunakan ViewBag, tetapi dalam kasus ini, untuk fleksibilitas, saya akan membuat pengecualian. Inilah yang akan saya lakukan ...
Anda harus memiliki pengontrol dasar di semua pengontrol Anda. Tambahkan data Layout Anda OnActionExecuting di pengontrol dasar Anda (atau OnActionExecuted jika Anda ingin menunda itu) ...
Kemudian di _Layout.cshtml Anda, tarik ViewModel dari ViewBag ...
Atau...
Melakukan ini tidak mengganggu pengkodean untuk pengontrol halaman atau model tampilan Anda.
sumber
MyLayoutViewModel
dibuat secara dinamis, bagaimana saya dapat mengirimkan beberapa parameter keOnActionExecuting
metode?base.OnActionExecuting(filterContext)
AndaOnActionExecuting
!!!Membuat tampilan dasar yang mewakili model tampilan Tata Letak adalah pendekatan yang buruk. Bayangkan Anda ingin memiliki model yang mewakili navigasi yang ditentukan dalam tata letak. Maukah kamu melakukannya
CustomersViewModel : LayoutNavigationViewModel
? Mengapa? Mengapa Anda harus meneruskan data model navigasi melalui setiap model tampilan yang Anda miliki dalam solusi?Model tampilan Tata Letak harus dikhususkan, dengan sendirinya dan tidak boleh memaksa model tampilan lainnya untuk bergantung padanya.
Sebagai gantinya, Anda dapat melakukan ini, di
_Layout.cshtml
file Anda :Yang terpenting, kami tidak perlu
new LayoutViewModel()
dan kami akan mendapatkan semua dependensi yangLayoutViewModel
telah diselesaikan untuk kami.misalnya
sumber
Scoped
objek model tata letak di ASP..Net Core juga.Jawaban lain telah mencakup hampir semua hal tentang bagaimana kita dapat mengirimkan model ke halaman tata letak kita. Tetapi saya telah menemukan cara yang dapat digunakan untuk meneruskan variabel ke halaman tata letak Anda secara dinamis tanpa menggunakan model atau tampilan parsial dalam tata letak Anda. Katakanlah Anda memiliki model ini -
Dan Anda ingin mendapatkan kota dan negara bagian secara dinamis. Misalnya
di index.cshtml Anda, Anda dapat meletakkan dua variabel ini di ViewBag
Lalu di layout.cshtml Anda, Anda dapat mengakses variabel viewbag tersebut
sumber
Ada cara lain untuk menangani ini. Mungkin bukan cara terbersih dari sudut pandang arsitektural, tetapi ini menghindari banyak rasa sakit yang terkait dengan jawaban lain. Cukup masukkan layanan dalam tata letak Razor, lalu panggil metode yang mendapatkan data yang diperlukan:
Kemudian nanti di tampilan tata letak:
Sekali lagi, tidak bersih dalam hal arsitektur (jelas layanan tidak boleh disuntikkan langsung ke tampilan), tetapi itu menyelesaikan pekerjaan.
sumber
@inject
adalah solusi terbaik, menurut saya.Anda juga dapat menggunakan RenderSection , ini membantu Anda untuk memasukkan
Model
data Anda ke file_Layout
tampilan.Anda dapat menyuntikkan
View Model
Data,Json
,Script
,CSS
,HTML
dllDalam contoh ini saya menyuntikkan
Json
dariIndex
View saya keLayout
View saya.Index.chtml
_Layout.cshtml
Ini menghilangkan kebutuhan untuk membuat Basis terpisah
View Model
.Harapan membantu seseorang.
sumber
apa yang saya lakukan sangat sederhana dan berhasil
Deklarasikan properti Statis di pengontrol apa pun atau Anda dapat membuat kelas data dengan nilai statis jika Anda ingin seperti ini:
Nilai-nilai ini dapat diperbarui oleh pengontrol berdasarkan operasi. nanti Anda dapat menggunakannya di _Layout Anda
Dalam _layout.cshtml
sumber
Mengapa tidak ada yang menyarankan metode ekstensi pada ViewData?
Pilihan 1
Menurut saya sejauh ini solusi yang paling tidak mengganggu dan paling sederhana untuk masalah ini. Tidak ada string hardcode. Tidak ada batasan yang diberlakukan. Tidak ada pengkodean ajaib. Tidak ada kode yang rumit.
Atur data di halaman
Pilihan 2
Pilihan lain, membuat deklarasi lapangan lebih mudah.
Atur data di halaman. Deklarasi lebih mudah daripada opsi pertama, tetapi sintaks penggunaan sedikit lebih panjang.
Opsi # 3
Kemudian dapat menggabungkannya dengan mengembalikan satu objek yang berisi semua bidang terkait tata letak dengan nilai defaultnya.
Atur data di halaman
Opsi ketiga ini memiliki beberapa manfaat dan menurut saya merupakan opsi terbaik dalam banyak kasus:
Deklarasi bidang dan nilai default paling sederhana.
Sintaks penggunaan paling sederhana saat mengatur beberapa bidang.
Memungkinkan pengaturan berbagai jenis data di ViewData (mis. Tata Letak, Header, Navigasi).
Mengizinkan kode dan logika tambahan dalam kelas LayoutData.
PS Jangan lupa untuk menambahkan namespace ViewDataExtensions di _ViewImports.cshtml
sumber
Anda dapat membuat file pisau cukur di folder App_Code dan kemudian mengaksesnya dari halaman tampilan Anda.
Proyek> Repositori / IdentityRepository.cs
Project> App_Code / IdentityRepositoryViewFunctions.cshtml:
Project> Views / Shared / _Layout.cshtml (atau file .cshtml lainnya)
sumber
alih-alih melalui ini, Anda selalu dapat menggunakan pendekatan lain yang juga cepat
buat tampilan parsial baru di Direktori Bersama dan panggil tampilan parsial Anda di tata letak sebagai
dalam tampilan parsial Anda, Anda dapat memanggil db Anda dan melakukan apa pun yang ingin Anda lakukan
dengan asumsi Anda telah menambahkan Database Kerangka Kerja Entitas Anda
sumber
Sungguh luar biasa bahwa tidak ada yang mengatakan ini di sini. Meneruskan model tampilan melalui pengontrol dasar akan berantakan. Kami menggunakan klaim pengguna untuk meneruskan info ke halaman tata letak (untuk menampilkan data pengguna di bilah navigasi misalnya). Ada satu keuntungan lagi. Data disimpan melalui cookie, jadi tidak perlu mengambil data di setiap permintaan melalui parsial. Lakukan saja beberapa googling "klaim identitas bersih asp".
sumber
Anda bisa menggunakan seperti ini:
sumber