134

I have two buttons on my MVC form:

<input name="submit" type="submit" id="submit" value="Save" />
<input name="process" type="submit" id="process" value="Process" />

From my Controller action how do I know which one have been pressed?

Brendan Vogt
  • 23,956
  • 33
  • 133
  • 226
Coppermill
  • 6,348
  • 13
  • 62
  • 90
  • Why not just add onclick events to these buttons that go to their own AJAX call which will go to their appropriate methods? ie: ``? – ragerory Mar 26 '15 at 18:25

11 Answers11

177

Name both your submit buttons the same

<input name="submit" type="submit" id="submit" value="Save" />
<input name="submit" type="submit" id="process" value="Process" />

Then in your controller get the value of submit. Only the button clicked will pass its value.

public ActionResult Index(string submit)
{
    Response.Write(submit);
    return View();
}

You can of course assess that value to perform different operations with a switch block.

public ActionResult Index(string submit)
{
    switch (submit)
    {
        case "Save":
            // Do something
            break;
        case "Process":
            // Do something
            break;
        default:
            throw new Exception();
            break;
    }

    return View();
}
Gone Coding
  • 88,305
  • 23
  • 172
  • 188
WDuffy
  • 7,498
  • 5
  • 35
  • 42
  • 13
    Beware the issues that localisation could bring to this solution, to which Darin's solution is not susceptable. – Richard Szalay Nov 27 '09 at 08:23
  • Two inputs with the same name results in an array being posted with one element for each value, not a single value as implied. So I wish I could say otherwise since I was hoping/trying to use this, but this does not work. – Christopher King Feb 09 '17 at 20:20
  • 1
    @RichardSzalay - couldn't you just use `` for i18n purposes, so the user facing string is customizable, and form element names are never directly exposed to the user (which is odd in and of itself) – KyleMit Mar 19 '18 at 16:53
51
<input name="submit" type="submit" id="submit" value="Save" />
<input name="process" type="submit" id="process" value="Process" />

And in your controller action:

public ActionResult SomeAction(string submit)
{
    if (!string.IsNullOrEmpty(submit))
    {
        // Save was pressed
    }
    else
    {
        // Process was pressed
    }
}
Darin Dimitrov
  • 960,118
  • 257
  • 3,196
  • 2,876
  • 1
    I imagine more buttons could be added by simply adding it to the parameter list and naming it correctly. Nice solution! – GONeale Aug 30 '11 at 00:34
36

this is a better answer, so we can have both text and value for a button:

http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form.aspx

</p>
<button name="button" value="register">Register</button>
<button name="button" value="cancel">Cancel</button>
</p>

and the controller:

public ActionResult Register(string button, string userName, string email, string password, string confirmPassword)
{
if (button == "cancel")
    return RedirectToAction("Index", "Home");
...

in short its a SUBMIT button but you choose the name using the name attribute, its even more powerful because your not obligated to the name submit or button in the controller method parameters, you can call it as you like...

Yakir Manor
  • 4,409
  • 1
  • 28
  • 24
  • Thanks Sir, this is exactly what I need – oHoodie Mar 05 '15 at 08:52
  • This breaks if you have a multilingual system that changes value of button according to language. – Dave Tapson Mar 12 '19 at 00:24
  • Dave - I don't think anyone would code a system like that. That's like localising your controller names or function names. The **value** of the button is for server side use only - it doesn't display anywhere and doesn't need to be localised. – NickG Jun 25 '20 at 13:26
20

you can identify your button from there name tag like below, You need to check like this in you controller

if (Request.Form["submit"] != null)
{
//Write your code here
}
else if (Request.Form["process"] != null)
{
//Write your code here
}
Kinjal Gohil
  • 888
  • 7
  • 14
6

Here's a really nice and simple way of doing it with really easy to follow instructions using a custom MultiButtonAttribute:

http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx

To summarise, make your submit buttons like this:

<input type="submit" value="Cancel" name="action" />
<input type="submit" value="Create" name="action" /> 

Your actions like this:

[HttpPost]
[MultiButton(MatchFormKey="action", MatchFormValue="Cancel")]
public ActionResult Cancel()
{
    return Content("Cancel clicked");
}

[HttpPost]
[MultiButton(MatchFormKey = "action", MatchFormValue = "Create")]
public ActionResult Create(Person person)
{
    return Content("Create clicked");
} 

And create this class:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultiButtonAttribute : ActionNameSelectorAttribute
{
    public string MatchFormKey { get; set; }
    public string MatchFormValue { get; set; }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        return controllerContext.HttpContext.Request[MatchFormKey] != null &&
            controllerContext.HttpContext.Request[MatchFormKey] == MatchFormValue;
    }
}
Owen
  • 3,623
  • 5
  • 39
  • 47
  • 1
    Always best to summarize a referenced link (for the day that blog vanishes). In summary that blog advocates having a `MultiButtonAttribute` custom attribute to allow differentiating between submit buttons. Actually quite a nice idea. – Gone Coding Aug 28 '14 at 12:51
  • 1
    And if `Arnis L.` had followed the same advice, you may have noticed that he provided the exact same link 4 years earlier :> – Gone Coding Aug 28 '14 at 12:52
3

To make it easier I will say you can change your buttons to the following:

<input name="btnSubmit" type="submit" value="Save" />
<input name="btnProcess" type="submit" value="Process" />

Your controller:

public ActionResult Create(string btnSubmit, string btnProcess)
{
    if(btnSubmit != null)
       // do something for the Button btnSubmit
    else 
       // do something for the Button btnProcess
}
Gone Coding
  • 88,305
  • 23
  • 172
  • 188
3
// Buttons
<input name="submit" type="submit" id="submit" value="Save" />
<input name="process" type="submit" id="process" value="Process" />

// Controller
[HttpPost]
public ActionResult index(FormCollection collection)
{
    string submitType = "unknown";

    if(collection["submit"] != null)
    {
        submitType = "submit";
    }
    else if (collection["process"] != null)
    {
        submitType = "process";
    }

} // End of the index method
  • This is a superior solution to everything else posted as it allows very complex form data to be passed in consistently without customized parameter sets in each action, allowing the controller logic to be highly customizeable for complex forms. Kudos Fredrik :) I assume this FormCollection would pass in multiple forms? – Stokely Aug 24 '17 at 22:38
  • Thank you Stokely. You can call this method from multiple forms, if you do a ajax call then you can include many forms in the same FormCollection. – Fredrik Stigsson Aug 30 '17 at 05:06
2

This post is not going to answer to Coppermill, because he have been answered long time ago. My post will be helpful for who will seeking for solution like this. First of all , I have to say " WDuffy's solution is totally correct" and it works fine, but my solution (not actually mine) will be used in other elements and it makes the presentation layer more independent from controller (because your controller depend on "value" which is used for showing label of the button, this feature is important for other languages.).

Here is my solution, give them different names:

<input type="submit" name="buttonSave" value="Save"/>
<input type="submit" name="buttonProcess" value="Process"/>
<input type="submit" name="buttonCancel" value="Cancel"/>

And you must specify the names of buttons as arguments in the action like below:

public ActionResult Register(string buttonSave, string buttonProcess, string buttonCancel)
{
    if (buttonSave!= null)
    {
        //save is pressed
    }
    if (buttonProcess!= null)
    {
        //Process is pressed
    }
    if (buttonCancel!= null)
    {
        //Cancel is pressed
    }
}

when user submits the page using one of the buttons, only one of the arguments will have value. I guess this will be helpful for others.

Update

This answer is quite old and I actually reconsider my opinion . maybe above solution is good for situation which passing parameter to model's properties. don't bother yourselves and take best solution for your project.

Rami A.
  • 9,490
  • 4
  • 37
  • 80
Ali Fattahian
  • 343
  • 1
  • 5
  • 21
  • Some constructive criticism along: this is well covered by the existing answers as of your posting this. Additionally, this doesn't scale well. HTML will only post back the `input[type=submit]` value that was triggered, so they can all model bind to a property with the same `name` (ex. `action`) and then you can differentiate buttons based on the `value` of that string without the need to introduce that many variables in your signature. Please also take some time to think about formatting / indentation before posting. – KyleMit Mar 19 '18 at 16:45
0

Can you not find out using Request.Form Collection? If process is clicked the request.form["process"] will not be empty

chugh97
  • 8,936
  • 24
  • 81
  • 132
0

Give the name to both of the buttons and Get the check the value from form.

<div>
   <input name="submitButton" type="submit" value="Register" />
</div>

<div>
   <input name="cancelButton" type="submit" value="Cancel" />
</div>

On controller side :

public ActionResult Save(FormCollection form)
{
 if (this.httpContext.Request.Form["cancelButton"] !=null)
 {
   // return to the action;
 }

else if(this.httpContext.Request.Form["submitButton"] !=null)
 {
   // save the oprtation and retrun to the action;
 }
}
Aniket Sharma
  • 956
  • 9
  • 16
0

In Core 2.2 Razor pages this syntax works:

    <button type="submit" name="Submit">Save</button>
    <button type="submit" name="Cancel">Cancel</button>
public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
        return Page();
    var sub = Request.Form["Submit"];
    var can = Request.Form["Cancel"];
    if (sub.Count > 0)
       {
       .......
Leftware
  • 59
  • 3
  • It might work, but I prefer parameter `string submit` vs writing `string submit = Request.Form["Submit"];`. One of the biggest benefits of Razor Pages and/or MVC is the readability of the methods, otherwise it could be PHP. – yzorg Jun 23 '20 at 18:34