Detecting which button was clicked in MVC

I’ve seen a few hacks in the past to try and work out which button caused a form POST in ASP.NET MVC, but the truth is it is pretty easy.

Step 1: Inside your form, add two Submit buttons. Add a name attribute to both (note it isn’t added by MVC by default);

    1:  <p>
    2:      <input type="submit" name="Command" value="Save" />
    3:      <input type="submit" name="Command" value="Delete" />
    4:  </p>

Note both have the same name.

Step 2: Inside your action, add a parameter that matches the name of the buttons;

    1:  [HttpPost]
    2:  public ActionResult Index(
    3:      Person person, 
    4:      string command)
    5:  {
    6:      bool saved = (command == "Save");
    8:      if (saved)
    9:          // code removed
   10:      else
   11:          // code removed
   12:  }

Simple huh? You could write some clever extension method to inspect the posted HTTP values, but I find this approach far more elegant. It is really clear that I’m expecting the “command” to be posted to my action.

A part of me wonders if naming all your buttons the same contravenes the HTML specification, but I can find no evidence of this – it is an accepted practice for checkboxes and radio buttons of course, and I’ve found this to work well. If you know otherwise do shout up. Like it? Hate it?

Step 3: Well… let’s take it one step further and create an enum of commands;

    1:  public enum Command
    2:  {
    3:      Save,
    4:      Delete
    5:  }

Step 4: … and update our action method parameter’s type to be our new enum, and of course our logic to use it;

    1:  [HttpPost]
    2:  public ActionResult Index(
    3:      Person person, 
    4:      Command command)
    5:  {
    6:      if (command == Command.Save)
    7:          // code removed
    8:      else
    9:          // code removed
   10:  }

Hey presto! Strongly typed clear code that reacts to which button was clicked.