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