Question

Handle Multiple Submit Buttons in ASP.NET MVC with C#

htmlcsharpasp.net-mvchttp-postform-submit

Question

How can an ASP.NET MVC application handle multiple submit buttons in the same form? For example, this form contains Send and Cancel buttons:

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

How can the controller determine which button the user clicked and run the appropriate logic?

Short Answer

A form can contain multiple submit buttons. Give the buttons the same name and different value attributes, then receive that value in the POST action. The clicked submit button is the one whose name/value pair is sent with the form, allowing the controller to choose between operations such as Send and Cancel.

Concept

HTML forms submit a collection of named values to the server. Text inputs, hidden inputs, checkboxes, and the submit button that triggered the submission can all contribute values.

For multiple submit buttons, the important rule is:

  • Give each button a name.
  • Give each possible operation a distinct value.
  • Use the submitted value in the controller to decide what to do.

A submit button without a name may display correctly, but it does not provide a useful value for ASP.NET MVC model binding. By naming the buttons, the browser can submit the selected operation alongside the rest of the form data.

This matters because one form often represents one piece of data but offers several outcomes: save a draft, publish, delete, cancel, or preview. The controller needs a reliable way to identify the requested outcome.

Mental Model

Think of a form as an envelope containing the user's entered data. Each submit button is a different instruction stamp placed on the envelope.

  • Clicking Send places command=Send on the envelope.
  • Clicking Cancel places command=Cancel on the envelope.

The controller opens the envelope, reads the instruction, and follows that path. The rest of the form data can be the same for both operations.

Take Quiz

Syntax and Examples

Use submit inputs with a shared name such as command and unique values:

<% 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 command in the POST action:

[HttpPost]
public ActionResult MyAction(string message, string command)
{
    if (command == "Send")
    {
        // Save or send the message.
        return RedirectToAction("Sent");
    }

    if (command == "Cancel")
    {
        // Do not perform the send operation.
        return RedirectToAction("Index");
    }

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

When the user clicks Send, the request includes a value similar to command=Send. When they click Cancel, it includes command=Cancel. ASP.NET MVC binds that posted value to the command parameter.

Step by Step Execution

Consider this form:

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

And this controller action:

[HttpPost]
public ActionResult Compose(string subject, string command)
{
    if (command == "Send")
    {
        return Content("Message sent: " + subject);
    }

    return Content("Message cancelled.");
}

If the user clicks Send:

  1. The browser gathers successful form fields.
  2. It includes subject=Hello.
  3. It includes command=Send because Send triggered submission.
  4. MVC binds subject to "Hello" and command to "Send".
  5. The if condition is true, so the send branch runs.

If the user clicks Cancel, the request instead contains command=Cancel, so the controller returns the cancellation result.

Real World Use Cases

Multiple submit buttons are common when a single edit screen supports more than one workflow:

  • Article editor: Save Draft, Publish, Preview, or Delete.
  • Shopping cart: Update Quantity, Apply Coupon, or Checkout.
  • Support ticket: Save, Assign, Close, or Reopen.
  • Administration form: Save Changes or Reset to Defaults.
  • Account form: Update Profile or Cancel and return without saving.
  • Approval workflow: Approve, Reject, or Request Changes.

The submitted command tells the server which operation is intended while the form model supplies the data needed by that operation.

Take Quiz

Real Codebase Usage

In production MVC applications, a common pattern is to bind form fields to a view model and receive a separate command parameter:

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

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

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

    productService.Update(model);
    return RedirectToAction("Details", new { id = model.Id });
}

This ordering is intentional:

  • Cancel is an early return. It usually does not need to save data.
  • Unknown commands are rejected. Do not silently treat an unexpected value as Save.
  • Validation occurs before the save operation. Invalid data returns the same view with validation messages.
  • Business logic lives in a service. The controller selects the workflow; it should not contain every database or domain operation.

For operations with significantly different authorization, validation, or business behavior, separate POST actions or endpoints can be clearer than a single large action.

Common Mistakes

Omitting the name attribute

This form does not tell the server which button was clicked:

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

Fix it by adding a name and distinct values:

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

Giving buttons different names but expecting one parameter

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

This can work, but the controller must inspect two possible parameters. A shared name is usually simpler:

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

Using display text as a fragile command

If the value is "Send" and the UI is translated, controller logic tied to that text can become fragile. Prefer stable machine-readable values and separate display text when possible:

<button type="submit" name="command" value="send">Send message</button>
<button type="submit" name="command" value="cancel">Cancel</button>

Then compare command with "send" and "cancel".

Saving before checking the command

productService.Update(model);

if (command == "Cancel")
{
    return RedirectToAction("Index");
}

This saves even when the user chose Cancel. Check cancellation before performing side effects.

Treating every non-Send value as Cancel

if (command == "Send")
{
    // Save
}
else
{
    // Cancel
}

A missing or unexpected value would incorrectly be treated as Cancel. Handle known commands explicitly and reject invalid values.

Comparisons

ApproachHow it worksBest use
Same action, shared command nameOne POST action receives command=send, command=cancel, and so on.Related operations sharing the same form and much of the same data.
Different formaction valuesEach button posts to a different URL.Modern HTML applications where each operation has a clearly separate endpoint.
Separate formsEach operation has its own <form>.Destructive or independent actions such as Delete, where clarity matters more than sharing fields.
JavaScript click handlerJavaScript changes hidden fields or submits requests.Enhanced interactions, but should not be required for normal server-side behavior.

A single action with a command parameter is concise, but avoid letting it grow into a long chain of unrelated operations. When actions have very different rules, separate endpoints are easier to test and secure.

Take Quiz

Cheat Sheet

<!-- HTML / ASPX markup -->
<button type="submit" name="command" value="save">Save</button>
<button type="submit" name="command" value="cancel">Cancel</button>
[HttpPost]
public ActionResult Edit(EditViewModel model, string command)
{
    if (command == "cancel")
    {
        return RedirectToAction("Index");
    }

    if (command == "save")
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // Save model
        return RedirectToAction("Index");
    }

    return new HttpStatusCodeResult(400);
}
  • Only the submit button used to submit the form normally contributes its name/value pair.
  • The button needs a name for MVC to bind its value.
  • Use one shared name such as command, action, or operation.
  • Use stable values such as save, draft, and cancel rather than presentation text when possible.
  • Handle cancel and other no-save operations before persistence.
  • Validate and reject unknown command values.

FAQ

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

The browser includes the clicked submit button's name and value in the POST request. MVC model binding places that value in a matching action parameter.

Do both submit button values get posted?

Normally, no. Only the submit button that triggered the form submission is included.

Must multiple submit buttons have the same name?

No, but using the same name with different values makes the controller simpler because it receives one parameter, such as command.

Can I use a button element instead of an input element?

Yes. A <button type="submit" name="command" value="save">Save</button> works well and lets you use display text separate from the posted value.

Should Cancel validate the form?

Usually no. Put the Cancel branch before ModelState.IsValid and redirect without saving. The exact behavior depends on your application requirements.

Is it better to use one controller action or separate actions?

Use one action for closely related commands with shared data and rules. Prefer separate actions when operations have substantially different authorization, validation, or side effects.

What if command is null?

Treat it as an invalid request or choose a documented default. Do not accidentally perform a save merely because the command is missing.

Take Quiz

Mini Project

Description

Build an ASP.NET MVC product editor with two operations: Save Draft and Publish. Both buttons submit the same product data, but publishing requires a price while saving a draft does not. This demonstrates how the clicked button can select an application workflow.

Goal

Create one form that saves a product as a draft or publishes it based on the submitted command.

Requirements

Use one POST action to receive the product form and selected command. Provide Save Draft and Publish submit buttons with one shared name. Save Draft must work without a price. Publish must require a non-negative price. Redirect after a successful operation.

Take Quiz

Keep learning

Related questions

View more