Bagaimana Anda mengarahkan ulang ke halaman menggunakan kata kerja POST?

131

Saat Anda memanggil RedirectToActiondalam pengontrol, pengalihan secara otomatis menggunakan HTTP GET. Bagaimana saya secara eksplisit mengatakannya untuk menggunakan HTTP POST?

Saya memiliki tindakan yang menerima permintaan GET dan POST, dan saya ingin dapat RedirectToActionmenggunakan POST dan mengirimkannya beberapa nilai.

Seperti ini:

this.RedirectToAction(
    "actionname",
    new RouteValueDictionary(new { someValue = 2, anotherValue = "text" })
);

Saya ingin someValuedan anotherValuenilai dikirim menggunakan HTTP POST bukan GET. Adakah yang tahu bagaimana melakukan ini?

Chris Pietschmann
sumber
Posting jawaban oleh jason akan berfungsi di sebagian besar skenario, satu-satunya masalah yang saya lihat adalah rawan kecelakaan. yaitu Memanggil metode tindakan langsung memotong semua filter yang diterapkan pada tindakan. Jadi, jika ada otentikasi atau semacam counter filter yang diterapkan pada metode tindakan, data itu mungkin hilang. Memanggil metode tindakan secara langsung akan berhasil, tetapi harus diterapkan dengan hati-hati.
amarnath chatterjee

Jawaban:

103

HTTP tidak mendukung pengalihan ke halaman menggunakan POST. Saat Anda mengarahkan ulang suatu tempat, tajuk "Lokasi" HTTP memberi tahu peramban ke mana harus pergi, dan peramban membuat permintaan GET untuk laman itu. Anda mungkin harus menulis kode untuk halaman Anda untuk menerima permintaan GET serta permintaan POST.

Eli Courtwright
sumber
4
Penasaran mengapa jawaban saya tidak diterima, saya pikir retorika saya bagus. :) Kemudian lagi, saya mungkin sedikit bias tentang hal itu ...
Jason Bunting
14
Meskipun jawaban ini pada dasarnya benar, itu tidak lengkap. Lihat jawaban Jason Bunting di bawah ini untuk solusi yang lebih baik.
Adrian Grigore
160

Sebagai contoh khusus Anda, saya hanya akan melakukan ini, karena Anda jelas tidak peduli tentang bagaimana sebenarnya peramban mendapatkan pengalihan (berdasarkan menerima jawaban yang telah Anda terima):

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index() {
   // obviously these values might come from somewhere non-trivial
   return Index(2, "text");
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(int someValue, string anotherValue) {
   // would probably do something non-trivial here with the param values
   return View();
}

Itu bekerja dengan mudah dan tidak ada bisnis lucu yang benar-benar terjadi - ini memungkinkan Anda untuk mempertahankan fakta bahwa yang kedua benar-benar hanya menerima permintaan HTTP POST (kecuali dalam hal ini, yang tetap berada di bawah kendali Anda) dan Anda tidak perlu gunakan TempData, yang disarankan oleh tautan yang Anda poskan di jawaban.

Saya ingin tahu apa yang "salah" dengan ini, jika ada sesuatu. Jelas, jika Anda ingin benar-benar mengirim pengalihan ke peramban, ini tidak akan berfungsi, tetapi kemudian Anda harus bertanya mengapa Anda mencoba mengonversi itu terlepas, karena sepertinya aneh bagi saya.

Semoga itu bisa membantu.

Jason Bunting
sumber
7
Siapa yang tahu mengapa Anda diturunkan suara. Ini adalah metode yang sangat berguna.
Peter J
2
Inilah bagaimana saya selalu memecahkan masalah ini juga. Downvoting ini tidak masuk akal.
Adrian Grigore
39
Saya memilih, meskipun saya tidak setuju dengan memanggil orang-orang idiot ketika Anda tidak mengenal mereka.
Jim Schubert
3
Saya bukan downvoter, tapi yang perlu diperhatikan adalah jika Anda memanggil tampilan dengan nama yang berbeda, atau jika parameternya penting, mereka akan hilang. Alasannya adalah URL akan mencerminkan parameter tindakan + sebelum pengarahan sisi server. Ini dapat menyebabkan kebingungan oleh pengguna, terutama jika mereka me-refresh halaman dan kemudian menemukan diri mereka di halaman sebelumnya (karena refresh menggunakan URL lama). Teknik ini pada dasarnya sangat mirip dengan Server.Transfer asp.net, dan peringatan yang sama harus dilakukan.
AaronLS
15
Saya tidak downvote per se tapi saya bisa melihat alasannya Metode ini melanggar konvensi pengkodean yang diatur oleh pola MVC. Ini hanya berfungsi saat memanggil tindakan yang sama. Jika tindakan lain, bahkan pada pengontrol yang sama, nilai-nilai perutean kacau dan tampilan yang salah akan dikembalikan. Singkatnya: Jangan lakukan ini.
erlando
21

Jika Anda ingin meneruskan data antara dua tindakan selama pengalihan tanpa menyertakan data apa pun dalam string kueri, masukkan model ke objek TempData.

TINDAKAN

TempData["datacontainer"] = modelData;

MELIHAT

var modelData= TempData["datacontainer"] as ModelDataType; 

TempData dimaksudkan untuk menjadi contoh yang sangat singkat, dan Anda hanya boleh menggunakannya selama permintaan saat ini dan berikutnya saja! Karena TempData bekerja dengan cara ini, Anda perlu tahu pasti apa permintaan berikutnya, dan mengarahkan ke tampilan lain adalah satu-satunya waktu Anda dapat menjamin ini.

Oleh karena itu, satu-satunya skenario di mana menggunakan TempData akan berfungsi adalah saat Anda mengarahkan ulang.

Otto Kanellis
sumber
11

coba yang ini

return Content("<form action='actionname' id='frmTest' method='post'><input type='hidden' name='someValue' value='" + someValue + "' /><input type='hidden' name='anotherValue' value='" + anotherValue + "' /></form><script>document.getElementById('frmTest').submit();</script>");
vicky
sumber
2
Benci tapi menyukainya :)
divinci
Peretasan seperti itu tapi itu satu-satunya cara saya bisa melakukan apa yang saya inginkan tanpa melanggar KERING atau memperbaiki seluruh pengaturan saya! Terima kasih!
jamheadart
6

Saya ingin memperluas jawaban Jason Bunting

seperti ini

ActionResult action = new SampelController().Index(2, "text");
return action;

Dan Eli akan ada di sini untuk ide sesuatu tentang bagaimana membuatnya menjadi variabel generik

Bisa mendapatkan semua jenis controller

Yitzhak Weinberg
sumber
Anda seharusnya tidak membuat instance ke controller dengan new ...()karena Anda akan kehilangan RequestContext- jika Anda sudah di controller yang sama, Anda mungkin tidak perlu membuat instance baru. Jika tidak, ambil cara berikut: SampelController sampleController = DependencyResolver.Current.GetService<SampelController>()lalu: sampleController.ControllerContext = new ControllerContext(Request.RequestContext, sampleController);maka Anda bisa return sampleController.Index(2, "text");Hanya memberi petunjuk :)
Matthias Burger