GET e POST alla stessa azione del controller in ASP.NET MVC


91

Mi piacerebbe che una singola azione rispondesse sia ai Gets che ai Post. Ho provato quanto segue

[HttpGet]
[HttpPost]
public ActionResult SignIn()

Non sembra funzionare. Eventuali suggerimenti ?


2
Per spiegare il problema: l'azione viene ignorata. Ogni attributo escluderà tutti gli altri metodi di richiesta, quindi l'azione finisce per non accettare alcun metodo di richiesta.
Guffa

In ASP.NET MVC2 e VisualStudio 2010 l'esempio dell'OP (con "[AcceptVerbs (HttpVerbs.Get)]", ecc.) Restituisce l'errore di compilazione: "Duplica l'attributo 'AcceptVerbs'".
DaveD

4
@ Dave Stai facendo [AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]o [AcceptVerbs(HttpVerbs.Get)][AcceptVerbs(HttpVerbs.Post)]? Non so nulla di quegli attributi, ma se stai facendo il secondo potrebbe essere il motivo per cui ricevi quell'errore.
Jared

Risposte:


134

Ciò è possibile utilizzando l'attributo AcceptVerbs. È un po 'più prolisso ma più flessibile.

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

Altro su msdn .


3
Sì, ma cosa succede se il metodo utilizza parametri (ad esempio SignIn (parametri SingInParams) ... per GET, sono presi da URI (quindi [FromUri] deve essere specificato) e per POST sono presi dal corpo (quindi [ FromBody] deve essere specificato)?
michal.jakubeczy

64

Le azioni rispondono a GET e POST per impostazione predefinita, quindi non devi specificare nulla:

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

A seconda delle proprie esigenze, è comunque possibile eseguire una logica diversa a seconda di HttpMethod operando sul valore HttpContext.Request.HttpMethod.


5
questo va bene finché non provi a usare i modelli di visualizzazione! nell'azione post che in genere passeresti nel viewmodel, ho provato a utilizzare un parametro opzionale e impostarlo di default su null ma non funziona.
JBeckton

1
@JBeckton Di solito ho un metodo GET che ha solo parametri di stringa di query SignIn(Guid? UserId)e POST ha un modello di visualizzazione SignIn(SomeVM vm)ed entrambi chiamano un metodo privato condiviso SignInHandleGetPost(...)... che forse prende VM che il metodo GET deve inizializzare, o parametri opzionali, o qualunque cosa tu preferisca fare per il refactoring del codice utilizzabile / condiviso.
AaronLS

2
@JBeckton L'ho appena provato ora con il progetto di esempio ASP.NET MVC 4.6.1, con il metodo AccountController.Login(String returnUrl, LoginViewModel model)e funziona bene. modelè nullo in GET e non nullo in POST. Tuttavia [ValidateForgeryToken]deve essere sovrascritto perché ValidateForgeryTokengenera un'eccezione sulle richieste GET.
Dai

0
[HttpGet]
public ActionResult SignIn()
{
}

[HttpPost]
public ActionResult SignIn(FormCollection form)
{
}

Non è quello che sto cercando, questa è l'implementazione MVC predefinita di avere metodi separati per GET e POST tramite il sovraccarico delle funzioni. Non sono nuovo in MVC, sto cercando di fare in modo che l'azione GET risponda anche a determinati eventi POST oltre all'azione POST standard per la raccolta di moduli.
Cranialsurge

Quindi devi seguire la risposta di Kurts. Nessun attributo gestirà entrambi. Se stai tentando di fare in modo che le richieste POST vadano ad azioni diverse, non è possibile. La tua azione dovrà eseguire la commutazione che stai cercando.
Jeremy B.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.