GET dan POST ke Controller Action yang sama di ASP.NET MVC

91

Saya ingin memiliki satu tindakan untuk menanggapi Gets dan Post. Saya mencoba yang berikut ini

[HttpGet]
[HttpPost]
public ActionResult SignIn()

Sepertinya itu tidak berhasil. Ada saran?

Cranialsurge
sumber
2
Untuk menjelaskan masalahnya: Tindakan tersebut diabaikan. Setiap atribut akan mengecualikan semua metode permintaan lainnya, sehingga tindakan tersebut akhirnya tidak menerima metode permintaan sama sekali.
Guffa
Dalam ASP.NET MVC2 dan VisualStudio 2010 contoh OP (dengan "[AcceptVerbs (HttpVerbs.Get)]", dll) memberikan kesalahan kompilasi: "Gandakan atribut 'AcceptVerbs'".
DaveD
4
@Dave Apakah Anda melakukan [AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]atau [AcceptVerbs(HttpVerbs.Get)][AcceptVerbs(HttpVerbs.Post)]? Saya tidak tahu apa-apa tentang atribut itu, tetapi jika Anda melakukan yang kedua, mungkin itulah sebabnya Anda mendapatkan kesalahan itu.
Jared

Jawaban:

134

Ini dimungkinkan dengan menggunakan atribut AcceptVerbs. Ini sedikit lebih bertele-tele tetapi lebih fleksibel.

[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]
public ActionResult SignIn()
{
}

Lebih lanjut tentang msdn .

Ryan Bair
sumber
3
Ya, tapi bagaimana jika metode menggunakan parameter (misalnya SignIn (parameter SingInParams) ... untuk GET, mereka diambil dari URI (jadi [FromUri] harus ditentukan) dan untuk POST mereka diambil dari tubuh (jadi [ FromBody] harus ditentukan)?
michal.jakubeczy
64

Tindakan menanggapi GET dan POST secara default, jadi Anda tidak perlu menentukan apa pun:

public ActionResult SignIn()
{
    //how'd we get here?
    string method = HttpContext.Request.HttpMethod;
    return View();
}

Bergantung pada kebutuhan Anda, Anda masih bisa melakukan logika yang berbeda bergantung pada HttpMethod dengan beroperasi pada nilai HttpContext.Request.HttpMethod.

Kurt Schindler
sumber
5
ini bagus sampai Anda mencoba menggunakan model tampilan! dalam tindakan posting Anda biasanya akan lulus di viewmodel, saya telah mencoba menggunakan parameter opsional dan default ke null tetapi itu tidak berhasil.
JBeckton
1
@JBeckton Biasanya saya memiliki metode GET yang hanya memiliki parameter string kueri SignIn(Guid? UserId)dan POST memiliki model tampilan SignIn(SomeVM vm)dan keduanya memanggil metode pribadi bersama SignInHandleGetPost(...)... yang mungkin menggunakan VM yang harus diinisialisasi oleh metode GET, atau parameter opsional, atau apa pun yang Anda sukai untuk refactoring kode ruseable / shared.
AaronLS
2
@JBeckton Saya baru saja mencobanya sekarang dengan proyek Contoh ASP.NET MVC 4.6.1, dengan metode AccountController.Login(String returnUrl, LoginViewModel model)dan bekerja dengan baik. modelbernilai null pada GET dan bukan null pada POST. Namun [ValidateForgeryToken]perlu diganti karena ValidateForgeryTokenmemunculkan pengecualian pada permintaan GET.
Dai
0
[HttpGet]
public ActionResult SignIn()
{
}

[HttpPost]
public ActionResult SignIn(FormCollection form)
{
}
Neil Outler
sumber
Bukan itu yang saya cari, itu adalah implementasi MVC default yang memiliki metode terpisah untuk GET dan POST melalui fungsi overloading. Saya bukan orang baru di MVC, saya mencoba agar tindakan GET juga menanggapi peristiwa POST tertentu selain tindakan POST standar untuk kumpulan formulir.
Cranialsurge
Maka Anda harus mengikuti jawaban Kurts. Tidak ada atribut yang akan menangani keduanya. Jika Anda mencoba agar permintaan POST beralih ke tindakan yang berbeda, itu tidak mungkin. Tindakan Anda harus melakukan pengalihan yang Anda cari.
Jeremy B.