Di ASP.NET MVC, Anda dapat mengembalikan ActionResult dengan cukup mudah:
return RedirectToAction("Index");
or
return RedirectToRoute(new { controller = "home", version = Math.Random() * 10 });
Ini sebenarnya akan memberikan pengalihan HTTP, yang biasanya baik-baik saja. Namun, ketika menggunakan google analytics, hal ini menyebabkan masalah besar karena perujuk asli hilang sehingga google tidak tahu dari mana Anda berasal. Ini akan menghilangkan informasi berguna seperti istilah mesin pencari.
Sebagai catatan tambahan, metode ini memiliki keuntungan untuk menghapus semua parameter yang mungkin berasal dari kampanye tetapi masih memungkinkan saya untuk menangkapnya dari sisi server. Membiarkannya dalam string kueri mengarahkan orang ke bookmark atau twitter atau blog link yang seharusnya tidak mereka lakukan. Saya telah melihat ini beberapa kali ketika orang-orang menge-tweet tautan ke situs kami yang berisi ID kampanye.
Bagaimanapun, saya menulis pengontrol 'gerbang' untuk semua kunjungan masuk ke situs yang dapat saya arahkan ke tempat yang berbeda atau versi alternatif.
Untuk saat ini saya lebih peduli tentang Google untuk saat ini (daripada bookmark yang tidak disengaja), dan saya ingin dapat mengirim seseorang yang mengunjungi /
ke halaman yang akan mereka dapatkan jika mereka membukanya /home/7
, yang merupakan versi 7 dari sebuah beranda.
Seperti yang saya katakan sebelumnya Jika saya melakukan ini, saya kehilangan kemampuan google untuk menganalisis perujuk:
return RedirectToAction(new { controller = "home", version = 7 });
Yang saya inginkan adalah a
return ServerTransferAction(new { controller = "home", version = 7 });
yang akan memberi saya tampilan tersebut tanpa pengalihan sisi klien. Saya tidak berpikir hal seperti itu ada.
Saat ini hal terbaik yang dapat saya hasilkan adalah menduplikasi seluruh logika pengontrol HomeController.Index(..)
dalam GatewayController.Index
Tindakan saya . Ini berarti saya harus pindah 'Views/Home'
ke 'Shared'
jadi itu dapat diakses. Pasti ada cara yang lebih baik ?? ..
sumber
ServerTransferAction
yang coba Anda tiru? Apakah itu hal yang nyata? (tidak dapat menemukan info apa pun tentang itu ... terima kasih atas pertanyaannya, btw, jawaban di bawah ini luar biasa)if
pernyataan sederhana terlalu menggoda solusi.RouteBase
sehingga Anda dapat meletakkanif
pernyataan Anda di sana alih-alih membengkokkan semuanya ke belakang untuk melompat dari satu pengontrol ke pengontrol lainnya?Jawaban:
Bagaimana dengan kelas TransferResult? (berdasarkan jawaban Stans )
Diperbarui: Sekarang bekerja dengan MVC3 (menggunakan kode dari posting Simon ). Ini seharusnya (belum mampu untuk menguji itu) juga bekerja di MVC2 dengan melihat apakah atau tidak itu berjalan dalam pipa terpadu IIS7 +.
Untuk transparansi penuh; Dalam lingkungan produksi kami, kami tidak pernah menggunakan TransferResult secara langsung. Kami menggunakan TransferToRouteResult yang pada gilirannya panggilan mengeksekusi TransferResult tersebut. Inilah yang sebenarnya berjalan di server produksi saya.
Dan jika Anda menggunakan T4MVC (jika tidak ... lakukan!) Ekstensi ini mungkin berguna.
Menggunakan permata kecil ini bisa Anda lakukan
sumber
Sunting: Diperbarui agar kompatibel dengan ASP.NET MVC 3
Asalkan Anda menggunakan IIS7, modifikasi berikut tampaknya berfungsi untuk ASP.NET MVC 3. Terima kasih kepada @nitin dan @andy karena menunjukkan kode asli tidak berfungsi.
Sunting 4/11/2011: TempData putus dengan Server.TransferRequest pada MVC 3 RTM
Memodifikasi kode di bawah ini untuk membuat pengecualian - tetapi tidak ada solusi lain untuk saat ini.
Berikut modifikasi saya berdasarkan versi modifikasi Markus dari posting asli Stan. Saya menambahkan konstruktor tambahan untuk mengambil kamus Route Value - dan menamainya MVCTransferResult untuk menghindari kebingungan bahwa itu mungkin hanya pengalihan.
Sekarang saya dapat melakukan hal berikut untuk pengalihan:
Kelas saya yang dimodifikasi:
sumber
Anda dapat menggunakan Server.TransferRequest di IIS7 + sebagai gantinya.
sumber
Saya baru-baru ini mengetahui bahwa ASP.NET MVC tidak mendukung Server.Transfer () jadi saya telah membuat metode rintisan (terinspirasi oleh Default.aspx.cs).
sumber
Tidak bisakah Anda membuat instance dari pengontrol yang ingin Anda alihkan, menjalankan metode tindakan yang Anda inginkan, lalu mengembalikan hasilnya? Sesuatu seperti:
sumber
otherController.ControllerContext = this.ControllerContext;
Saya ingin merutekan ulang permintaan saat ini ke pengontrol / tindakan lain, sambil menjaga jalur eksekusi persis sama seperti jika pengontrol / tindakan kedua diminta. Dalam kasus saya, Server.Request tidak akan berfungsi karena saya ingin menambahkan lebih banyak data. Ini sebenarnya setara dengan penangan saat ini yang menjalankan HTTP GET / POST lain, lalu mengalirkan hasilnya ke klien. Saya yakin akan ada cara yang lebih baik untuk mencapai ini, tetapi inilah yang berhasil untuk saya:
Tebakan Anda benar: Saya memasukkan kode ini
dan saya menggunakannya untuk menampilkan kesalahan kepada pengembang, sementara itu akan menggunakan pengalihan biasa dalam produksi. Perhatikan bahwa saya tidak ingin menggunakan sesi ASP.NET, database, atau beberapa cara lain untuk melewatkan data pengecualian antara permintaan.
sumber
Daripada mensimulasikan sebuah server transfer, MVC masih mampu benar-benar melakukan Server.TransferRequest :
sumber
Cukup contoh pengontrol lain dan jalankan metode aksinya.
sumber
Anda dapat memperbarui pengontrol lain dan menjalankan metode tindakan yang mengembalikan hasilnya. Ini akan meminta Anda untuk menempatkan tampilan Anda ke folder bersama.
Saya tidak yakin apakah ini yang Anda maksud dengan duplikat, tetapi:
Sunting
Pilihan lainnya adalah membuat ControllerFactory Anda sendiri, dengan cara ini Anda dapat menentukan pengontrol mana yang akan dibuat.
sumber
Bukankah perutean hanya menangani skenario ini untuk Anda? yaitu untuk skenario yang dijelaskan di atas, Anda bisa membuat penangan rute yang menerapkan logika ini.
sumber
Untuk siapa pun yang menggunakan perutean berbasis ekspresi, hanya menggunakan kelas TransferResult di atas, berikut adalah metode ekstensi pengontrol yang melakukan trik dan mempertahankan TempData. Tidak perlu TransferToRouteResult.
sumber
Server.TransferRequest
sama sekali tidak diperlukan di MVC . Ini adalah fitur kuno yang hanya diperlukan di ASP.NET karena permintaan datang langsung ke halaman dan perlu ada cara untuk mentransfer permintaan ke halaman lain. Versi modern ASP.NET (termasuk MVC) memiliki infrastruktur perutean yang dapat disesuaikan untuk merutekan langsung ke sumber daya yang diinginkan. Tidak ada gunanya membiarkan permintaan mencapai pengontrol hanya untuk mentransfernya ke pengontrol lain saat Anda dapat membuat permintaan langsung ke pengontrol dan tindakan yang Anda inginkan.Terlebih lagi, karena Anda menanggapi permintaan asli , tidak perlu memasukkan apa pun ke dalam
TempData
atau penyimpanan lain hanya untuk mengarahkan permintaan ke tempat yang tepat. Sebagai gantinya, Anda sampai pada aksi pengontrol dengan permintaan asli utuh. Anda juga dapat yakin bahwa Google akan menyetujui pendekatan ini karena ini terjadi sepenuhnya di sisi server.Meskipun Anda dapat melakukan sedikit dari keduanya
IRouteConstraint
danIRouteHandler
, titik ekstensi paling kuat untuk perutean adalahRouteBase
subkelas. Kelas ini dapat diperluas untuk menyediakan rute masuk dan pembuatan URL keluar, yang menjadikannya tempat serba ada untuk segala sesuatu yang berkaitan dengan URL dan tindakan yang dijalankan URL.Jadi, untuk mengikuti contoh kedua Anda, untuk pergi dari
/
ke/home/7
, Anda hanya memerlukan rute yang menambahkan nilai rute yang sesuai.Tetapi kembali ke contoh asli Anda di mana Anda memiliki halaman acak, itu lebih rumit karena parameter rute tidak dapat berubah saat runtime. Jadi, bisa dilakukan dengan
RouteBase
subclass sebagai berikut.Yang dapat didaftarkan dalam perutean seperti:
Perhatikan dalam contoh di atas, mungkin masuk akal untuk juga menyimpan cookie yang merekam versi halaman beranda tempat pengguna masuk sehingga ketika kembali, mereka menerima versi halaman beranda yang sama.
Perhatikan juga bahwa menggunakan pendekatan ini Anda dapat menyesuaikan perutean untuk mempertimbangkan parameter string kueri (ini sepenuhnya mengabaikannya secara default) dan merutekan ke tindakan pengontrol yang sesuai.
Contoh Tambahan
sumber
Server.TransferRequest
bukan "sama sekali tidak perlu di MVC".Bukan jawaban itu sendiri, tetapi jelas persyaratannya tidak hanya untuk navigasi yang sebenarnya untuk "melakukan" fungsi yang setara dari Webforms Server.Transfer (), tetapi juga agar semua ini didukung sepenuhnya dalam pengujian unit.
Oleh karena itu, ServerTransferResult harus "terlihat" seperti RedirectToRouteResult, dan semirip mungkin dalam hal hierarki kelas.
Saya berpikir untuk melakukan ini dengan melihat Reflector, dan melakukan apa pun kelas RedirectToRouteResult dan juga berbagai metode kelas dasar Controller lakukan, dan kemudian "menambahkan" yang terakhir ke Controller melalui metode ekstensi. Mungkin ini bisa menjadi metode statis dalam kelas yang sama, untuk kemudahan / kemalasan mengunduh?
Jika saya sempat melakukan ini, saya akan mempostingnya, jika tidak, mungkin orang lain akan mengalahkan saya!
sumber
Saya mencapai ini dengan memanfaatkan
Html.RenderAction
helper dalam sebuah View:Dan di pengontrol saya:
sumber