Question

Handling Multiple Submit Buttons in ASP.NET MVC

csharphtmlasp.net-mvchttp-postform-submit

Question

How can an ASP.NET MVC form handle multiple submit buttons, such as Send and Cancel, that post to the same controller action?

<% using (Html.BeginForm("MyAction", "MyController", FormMethod.Post))
   { %>
    <input type="submit" value="Send" />
    <input type="submit" value="Cancel" />
<% } %>

How can the controller determine which button the user clicked in the ASP.NET MVC Framework Beta?

Short Answer

You will learn that a submitted form includes the name and value of the submit button that was clicked. By giving each button a shared name and a distinct value, a controller action can decide whether to send, cancel, save, delete, or perform another operation.

Concept

HTML forms submit name/value pairs. Text inputs, checkboxes, hidden inputs, and the clicked submit button can all contribute values to the HTTP POST request.

A submit button without a name is not useful for identifying the user's choice on the server. Give the buttons the same name, such as command, and different values:

<input type="submit" name="command" value="Send" />
<input type="submit" name="command" value="Cancel" />

When the user clicks Send, the request contains command=Send. When they click Cancel, it contains command=Cancel.

In ASP.NET MVC, model binding maps that posted value to an action parameter with the same name. The action can then branch to the appropriate behavior.

This matters because one screen often offers several intentional outcomes: save a draft, submit a record, cancel editing, delete an item, or preview content. The server must not guess which outcome was intended.

Mental Model

Think of a form as an envelope containing labelled cards. Each form field puts one labelled card into the envelope, such as email=ada@example.com.

Each submit button is also a labelled card, but only the button the user presses is placed in the envelope. If the user presses Send, the envelope includes command=Send; if they press Cancel, it includes command=Cancel.

Your controller opens the envelope and reads the command card before deciding what to do.

Take Quiz

Syntax and Examples

Use a shared name and distinct value attributes for related submit buttons.

<% using (Html.BeginForm("MyAction", "MyController", FormMethod.Post))
   { %>
    <input type="text" name="message" />

    <input type="submit" name="command" value="Send" />
    <input type="submit" name="command" value="Cancel" />
<% } %>

Receive the selected value in the controller:

[HttpPost]
public ActionResult MyAction(string message, string command)
{
    if (command == "Cancel")
    {
        return RedirectToAction("Index");
    }

    if (command == "Send")
    {
        // Save or send the message.
        return RedirectToAction("Sent");
    }

    return new HttpStatusCodeResult(400, "Unknown command.");
}

The parameter name, command, matches the buttons' name="command". MVC binds the button's posted value to that parameter.

Step by Step Execution

Consider this form:

<% using (Html.BeginForm("MyAction", "Messages", FormMethod.Post))
   { %>
    <input type="text" name="message" value="Hello" />
    <input type="submit" name="command" value="Send" />
    <input type="submit" name="command" value="Cancel" />
<% } %>

And this action:

[HttpPost]
public ActionResult MyAction(string message, string command)
{
    if (command == "Cancel")
    {
        return Content("Nothing was sent.");
    }

    return Content("Sent: " + message);
}

If the user clicks Send:

  1. The browser collects the form fields.
  2. It posts message=Hello.
  3. Because Send was clicked, it also posts command=Send.
  4. MVC binds message to "Hello" and command to "Send".
  5. The Cancel condition is false, so the action returns Sent: Hello.

If the user clicks Cancel, the request contains command=Cancel. The action returns immediately without sending the message.

Real World Use Cases

  • Edit forms: provide Save, Save Draft, and Cancel choices.
  • Administrative pages: provide Approve and Reject actions for an application or review.
  • Shopping workflows: provide Place Order and Return to Cart buttons.
  • Content systems: let authors Preview, Publish, or Delete an article.
  • Support tools: let an agent Reply, Close Ticket, or Escalate a case.

For actions that are destructive, such as delete or publish, verify authorization and validate the current record state on the server. A button value is user input and must not be trusted by itself.

Take Quiz

Real Codebase Usage

A common MVC pattern is to post a view model plus a command value, then use guard clauses for commands that should not run full validation.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(OrderEditViewModel model, string command)
{
    if (command == "Cancel")
    {
        return RedirectToAction("Details", new { id = model.Id });
    }

    if (command != "Save" && command != "SaveDraft")
    {
        return new HttpStatusCodeResult(400, "Unknown command.");
    }

    if (!ModelState.IsValid)
    {
        return View(model);
    }

    if (command == "SaveDraft")
    {
        // Save an incomplete order.
        return RedirectToAction("Drafts");
    }

    // Save the completed order.
    return RedirectToAction("Details", new { id = model.Id });
}

Useful project practices include:

  • Use a descriptive name such as command, operation, or intent.
  • Use constants or an enum-like set of known command strings to avoid scattered typos.
  • Handle Cancel before validation when it should simply navigate away.
  • Return the same view with validation errors for save-related commands.
  • Add [ValidateAntiForgeryToken] to state-changing POST actions and render an anti-forgery token in the form.
  • Check permissions and record ownership on the server for every command.

Common Mistakes

Omitting the name attribute

This does not give the controller a reliable command value:

<input type="submit" value="Send" />
<input type="submit" value="Cancel" />

Fix it by adding a shared name:

<input type="submit" name="command" value="Send" />
<input type="submit" name="command" value="Cancel" />

Giving both buttons the same value

<input type="submit" name="command" value="Submit" />
<input type="submit" name="command" value="Submit" />

The server cannot tell them apart. Use unique values.

Matching the action parameter to value instead of name

This is incorrect because MVC matches input names to parameter names:

public ActionResult MyAction(string Send)

Use the input name instead:

public ActionResult MyAction(string command)

Trusting an unrecognized command

A client can send any posted value, not only values shown by your page. Reject unexpected values and perform authorization checks.

Validating before handling Cancel

If cancel should leave the page without saving, checking ModelState.IsValid first can block it because required fields may be empty. Handle the cancel command first.

Putting delete and save in one ambiguous branch

A delete command should have a clearly separate branch, authorization checks, and usually a confirmation step. Do not accidentally treat every non-cancel command as save.

Comparisons

ApproachBest forHow it worksNotes
One action with a command parameterRelated operations from one formButtons share a name and have different valuesSimple and common for Save/Cancel or Save Draft/Publish.
Separate controller actionsOperations with very different rulesEach button posts to a different endpointCan improve separation, especially for destructive actions.
JavaScript-based handlingEnhanced user interactionJavaScript intercepts clicks or changes the requestThe server should still validate the intended operation.
A link for CancelCancel that only navigates awayUse an <a> element instead of postingOften clearer because no state change is required.

A Cancel option is frequently better as a link when it does not need to submit any data:

<%= Html.ActionLink("Cancel", "Index") %>

Use a submit button for cancel only when the server must receive the cancellation request or record a workflow event.

Take Quiz

Cheat Sheet

<!-- Same name, distinct values -->
<input type="submit" name="command" value="Save" />
<input type="submit" name="command" value="Cancel" />
[HttpPost]
public ActionResult Edit(MyViewModel model, string command)
{
    if (command == "Cancel")
    {
        return RedirectToAction("Index");
    }

    if (command == "Save" && ModelState.IsValid)
    {
        // Save model
    }

    return View(model);
}
  • MVC binds an input's name to an action parameter.
  • The clicked submit button provides its value.
  • Only the clicked submit button is normally included in a browser form submission.
  • Treat command as untrusted input; allow only known values.
  • Handle navigation-only commands such as Cancel before model validation when appropriate.
  • Prefer a normal link for Cancel when no POST is needed.

FAQ

How does ASP.NET MVC know which submit button was clicked?

The browser posts the name=value pair for the submit button that initiated the form submission. MVC model binding maps that value to an action parameter with the same name.

Do multiple submit buttons need the same name?

Use the same name when they represent alternative commands for one action, such as command=Save and command=Cancel. This lets one parameter hold the selected command.

Can I use different names for each button?

Yes, but it is usually less convenient. You would need to test which parameter is present. A shared command name is clearer for mutually exclusive actions.

Why is my command parameter null?

Check that the clicked submit button has a name attribute and that its name matches the action parameter exactly. Also ensure the button is inside the submitted form and is not disabled.

Should Cancel be a submit button or a link?

Use a link if cancel only returns the user to another page. Use a submit button when the server must receive and process the cancellation.

Can a user modify the command value in the request?

Yes. Any client-side value can be changed. Validate the command against allowed values and enforce authorization and business rules on the server.

Can I use separate actions instead of one action with a command?

Yes. Separate actions can be a good design when operations have substantially different validation, permissions, or side effects.

Take Quiz

Mini Project

Description

Build an order-editing form with three user intentions: save a draft, submit an order, or cancel editing. The project demonstrates how one posted form can communicate the selected operation to an ASP.NET MVC controller.

Goal

Create an MVC POST action that reacts correctly to SaveDraft, Submit, and Cancel commands.

Requirements

Include an order number field in the form. Add three submit buttons that use the same command name. Redirect to the order list immediately when Cancel is selected. Return validation errors when Submit is selected without an order number. Display a different success message for Save Draft and Submit.

Take Quiz

Keep learning

Related questions

View more