POST fiilini kullanarak bir sayfaya nasıl yönlendirilirsiniz?


131

Bir RedirectToActiondenetleyicide arama yaptığınızda , bir HTTP GET kullanarak otomatik olarak yeniden yönlendirir. Açıkça bir HTTP POST kullanmasını nasıl söyleyebilirim?

Hem GET hem de POST isteklerini kabul eden bir eylemim var ve POST'u RedirectToActionkullanıp ona bazı değerler gönderebilmek istiyorum .

Bunun gibi:

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

someValueVe anotherValuedeğerlerinin GET yerine HTTP POST kullanılarak gönderilmesini istiyorum . Bunun nasıl yapılacağını bilen var mı?


Jason tarafından gönderilen cevap çoğu senaryoda işe yarayacak, gördüğüm tek sorun kazaya meyilli olmasıdır. Örneğin, bir eylem yönteminin çağrılması, eyleme uygulanan tüm filtreleri doğrudan atlar . Bu nedenle, eylem yöntemine uygulanan herhangi bir kimlik doğrulama veya sayaç türü filtre olması durumunda, bu veriler kaybolabilir. Doğrudan bir eylem yöntemini çağırmak işe yarayacaktır, ancak dikkatlice uygulanmalıdır.
amarnath chatterjee

Yanıtlar:


103

HTTP, POST kullanılarak bir sayfaya yönlendirmeyi desteklemez. Bir yere yeniden yönlendirdiğinizde, HTTP "Konum" başlığı tarayıcıya nereye gideceğini söyler ve tarayıcı o sayfa için bir GET isteğinde bulunur. GET isteklerini ve POST isteklerini kabul etmek için muhtemelen sayfanızın kodunu yazmanız gerekecektir.


4
Cevabımın neden kabul edilmediğini merak ediyorum, sanırım retoriğim sağlam. :) Sonra tekrar, bu konuda biraz önyargılı olabilirim ...
Jason Bunting

14
Bu cevap temelde doğru olsa da tam değildir. Daha iyi bir çözüm için aşağıdaki Jason Bunting cevabına bakın.
Adrian Grigore

160

Sizin özel örneğiniz için, bunu yapacağım, çünkü tarayıcının yine de yönlendirmeyi almasını gerçekten umursamadığınız için (zaten kabul ettiğiniz yanıtı kabul ettiğiniz için):

[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();
}

Bu kolayca çalışır ve gerçekten devam eden komik bir iş yoktur - bu, ikincisinin gerçekten yalnızca HTTP POST isteklerini kabul ettiği gerçeğini korumanıza olanak tanır (zaten sizin kontrolünüz altında olan bu durum hariç) ve bunu yapmak zorunda değilsiniz Ya TempData'yı kullanın, cevabınızda gönderdiğiniz bağlantının önerdiği şey budur.

Herhangi bir şey varsa bunda "yanlış" olanı bilmek isterim. Açıkçası, tarayıcıya gerçekten bir yönlendirme göndermek istiyorsanız, bu işe yaramayacaktır, ancak bana tuhaf göründüğü için neden bunu ne olursa olsun dönüştürmeye çalıştığınızı sormalısınız.

Umarım yardımcı olur.


7
Neden reddedildiğini kim bilebilir? Bu çok kullanışlı bir yöntemdir.
Peter J

2
Ben de bu sorunu hep böyle çözdüm. Buna olumsuz oy vermek mantıklı değil.
Adrian Grigore

39
Ben oy verdim, ama siz onları tanımadığınızda insanlara aptal demeye katılmıyorum.
Jim Schubert

3
Ben bir olumsuz oy veren değilim, ancak bununla ilgili bir uyarı, bir görünümü farklı bir adla çağırırsanız veya parametreler önemliyse, bunlar kaybolur. Bunun nedeni, URL'nin sunucu tarafı yönlendirmeden önce eylem + parametrelerini yansıtmasıdır. Bu, özellikle sayfayı yeniledikten sonra kendilerini önceki bir sayfada buldularsa (yenileme eski URL'yi kullandığı için) kullanıcı tarafından kafa karışıklığına yol açabilir. Bu teknik esasen asp.net'in Server.Transfer'ına çok benzer ve aynı uyarılar uygulanmalıdır.
AaronLS

15
Kendi başına olumsuz oy vermedim ama bunun için bir neden görebiliyorum. Bu yöntem, MVC modeli tarafından ayarlanan kodlama kuralını ihlal ediyor. Bu sadece aynı eylemi çağrılırken çalışır. Eylem başka ise, aynı denetleyicide bile, yönlendirme değerleri vidalanır ve yanlış görünüm döndürülür. Kısaca: Bunu yapmayın.
erlando

21

Bir yeniden yönlendirme sırasında sorgu dizesine herhangi bir veri eklemeden iki eylem arasında veri iletmek istiyorsanız, modeli TempData nesnesine yerleştirin.

AKSİYON

TempData["datacontainer"] = modelData;

GÖRÜNÜM

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

TempData'nın çok kısa ömürlü bir örnek olması amaçlanmıştır ve bunu yalnızca mevcut ve sonraki istekler sırasında kullanmalısınız! TempData bu şekilde çalıştığından, bir sonraki isteğin ne olacağından emin olmanız gerekir ve başka bir görünüme yeniden yönlendirmek, bunu garanti edebileceğiniz tek zamandır.

Bu nedenle, TempData kullanımının güvenilir bir şekilde çalışacağı tek senaryo, yeniden yönlendirme yaptığınız zamandır.


11

bunu dene

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>");

2
Nefret et ama sev :)
divinci

Böyle bir hack ama DRY'yi ihlal etmeden veya tüm kurulumumu yeniden kurmadan istediğimi yapabilmemin tek yolu buydu! Teşekkürler!
jamheadart

6

Jason Bunting'in cevabını genişletmek istiyorum

bunun gibi

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

Eli, onu genel değişken haline getirme konusunda bir fikir için burada olacak

Her tür denetleyiciyi alabilir


İle bir denetleyiciye örnek oluşturmamalısınız new ...()çünkü onu kaybedeceksiniz RequestContext- zaten aynı denetleyicide iseniz, yeni bir örnek oluşturmanız gerekmeyebilir. Aksi takdirde, aşağıdaki yolu kullanın: SampelController sampleController = DependencyResolver.Current.GetService<SampelController>()o zaman: sampleController.ControllerContext = new ControllerContext(Request.RequestContext, sampleController);o zaman yapabilirsiniz return sampleController.Index(2, "text");Sadece bir ipucu :)
Matthias Burger
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.