98

I'd like to have a single action respond to both Gets as well as Posts. I tried the following

[HttpGet]
[HttpPost]
public ActionResult SignIn()

That didn't seem to work. Any suggestions ?

tereško
  • 58,060
  • 25
  • 98
  • 150
Cranialsurge
  • 6,104
  • 7
  • 40
  • 39
  • 3
    To explain the problem: The action is ignored. Each attribute will exclude all other request methods, so the action ends up not accepting any request methods at all. – Guffa Nov 03 '11 at 10:47
  • In ASP.NET MVC2 and VisualStudio 2010 the OP's example (with "[AcceptVerbs(HttpVerbs.Get)]", etc) gives the compile error: "Duplicate 'AcceptVerbs' attribute". – DaveD Jul 30 '12 at 19:25
  • 4
    @Dave Are you doing `[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]` or `[AcceptVerbs(HttpVerbs.Get)][AcceptVerbs(HttpVerbs.Post)]` ? I don't know anything about those attributes but if you're doing the second that may be why you're getting that error. – Jesus is Lord Sep 04 '12 at 01:28

3 Answers3

140

This is possible using the AcceptVerbs attribute. Its a bit more verbose but more flexible.

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

More on msdn.

Ryan Bair
  • 2,614
  • 3
  • 18
  • 18
  • 3
    Yes, but what if the method uses parameters (e.g. SignIn(SingInParams parameters) ... for GET, they're taken from URI (so [FromUri] has to be specified) and for POST they're taken from body (so [FromBody] has to be specified)? – michal.jakubeczy Oct 24 '16 at 11:17
64

Actions respond to both GETs and POSTs by default, so you don't have to specify anything:

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

Depending on your need you could still perform different logic depending on the HttpMethod by operating on the HttpContext.Request.HttpMethod value.

Kurt Schindler
  • 21,037
  • 4
  • 43
  • 48
  • 5
    this is fine until you try to use view models! in the post action you would typically pass in the viewmodel, i have try using an optional param and default it to null but that does not work. – JBeckton Jan 25 '11 at 19:46
  • 1
    @JBeckton Usually I have a GET method that just has query string params `SignIn(Guid? UserId)` and POST has view model `SignIn(SomeVM vm)` and both call a shared private method `SignInHandleGetPost(...)`... which maybe takes VM that the GET method must initialize, or optional params, or whatever you prefer to do for refactoring the ruseable/shared code. – AaronLS Apr 22 '13 at 20:58
  • 2
    @JBeckton I just tried it now with the ASP.NET MVC 4.6.1 Sample project, with the method `AccountController.Login(String returnUrl, LoginViewModel model)` and it works fine. `model` is null on GET and non-null on POST. However `[ValidateForgeryToken]` needs to be overriden because `ValidateForgeryToken` throws an exception on GET requests. – Dai Jul 19 '16 at 12:25
4
[HttpGet]
public ActionResult SignIn()
{
}

[HttpPost]
public ActionResult SignIn(FormCollection form)
{
}
Neil Outler
  • 264
  • 3
  • 11
  • That is not what I am looking for, thats the default MVC implementation of having separate methods for GET and POST via function overloading. I am not new to MVC, I am trying to have the GET action also respond to certain POST events in addition to the standard POST action for the form collection. – Cranialsurge Jul 12 '10 at 22:45
  • Then you need to follow Kurts' answer. No attribute will handle both. If you are attempting to have POST requests going to different actions, that is not possible. Your action will have to perform the switching you are looking for. – Jeremy B. Sep 18 '10 at 02:49