April 2, 2018

Sreekanth B

How to Handle Multiple Submit Buttons In ASP.NET MVC

Is there some easy way to handle multiple submit buttons from the same form?

Example:

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

Any idea how to do this in ASP.NET Framework Beta? All examples I've googled for have single buttons in them.

Answer:

Here is a mostly clean attribute-based solution to the multiple submit button issue based heavily on the post and comments from Maartin Balliauw.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]

public class MultipleButtonAttribute : ActionNameSelectorAttribute
{
    public string Name { get; set; }
    public string Argument { get; set; }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        var isValidName = false;
        var keyValue = string.Format("{0}:{1}", Name, Argument);
        var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);

        if (value != null)
        {
            controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
            isValidName = true;
        }

        return isValidName;
    }
}

razor View:

<form action="" method="post">
 <input type="submit" value="Save" name="action:Save" />
 <input type="submit" value="Cancel" name="action:Cancel" />
</form>

controller:

[HttpPost]
[MultipleButton(Name = "action", Argument = "Save")]
public ActionResult Save(MessageModel mm) { ... }

[HttpPost]
[MultipleButton(Name = "action", Argument = "Cancel")]
public ActionResult Cancel(MessageModel mm) { ... }


Or Try This

There are three ways by which you can solve the above issue
  • HTML way
  • Jquery way
  • “ActionNameSelectorAttribute” way
HTML way :-

In the HTML way we need to create two forms and place the “Submit” button inside each of the forms. And every form’s action will point to different / respective actions. You can see the below code the first form is posting to “Action1” and the second form will post to “Action2” depending on which “Submit” button is clicked.

<form action="Action1" method=post>
<input type=”submit” name=”Submit1”/>
</form>

<form action="Action2" method=post>
<input type=”submit” name=”Submit2”>
</form>

Ajax way :-

In case you are a Ajax lover this second option would excite you more. In the Ajax way we can create two different functions “Fun1” and “Fun1” , see the below code. These functions will make Ajax calls by using JQUERY or any other framework. Each of these functions are binded with the “Submit” button’s “OnClick” events. Each of these function make call to respective action names.

<Script language="javascript">
function Fun1()
{
$.post(“/Action1”,null,CallBack1);
}
function Fun2()
{
$.post(“/Action2”,null,CallBack2);
}
</Script>

<form action="/Action1" method=post>
<input type=submit name=sub1 onclick=”Fun2()”/>
</form>
<form action="/Action2" method=post>
<input type=submit name=sub2 onclick=”Fun1()”/>
</form>

Using “ActionNameSelectorAttribute”:-

This is a great and a clean option. The “ActionNameSelectorAttribute” is a simple attribute class where we can write decision making logic which will decide which action can be executed.

So the first thing is in HTML we need to put proper name’s to the submit buttons for identifying them on the server.

You can see we have put “Save” and “Delete” to the button names. Also you can notice in the action we have just put controller name “Customer” and not a particular action name. We expect the action name will be decide by “ActionNameSelectorAttribute”.

<form action=”Customer” method=post>
<input type=submit value="Save" name="Save" /> <br />
<input type=submit value="Delete" name="Delete"/>
</form>
So when the submit button is clicked , it first hits the “ActionNameSelector” attribute and then depending on which submit is fired it invokes the appropriate action.

So the first step is to create a class which inherits from “ActionNameSelectorAttribute” class. In this class we have created a simple property “Name”.

We also need to override the “IsValidName” function which returns true or flase. This function is where we write the logic whether an action has to be executed or not. So if this function returns true then the action is executed or else it is not.

public class SubmitButtonSelector : ActionNameSelectorAttribute
    {
        public string Name { get; set; }
        public override bool IsValidName(ControllerContext controllerContext, string actionName, System.Reflection.MethodInfo methodInfo)
        {
            // Try to find out if the name exists in the data sent from form
var value = controllerContext.Controller.ValueProvider.GetValue(Name);
            if (value != null)
            {
                return true;
            }
            return false;

        }
    }
The main heart of the above function is in the below code. The “ValueProvider” collection has all the data that has been posted from the form. So it first looks up the “Name” value and if its found in the HTTP request it returns true or else it returns false.

var value = controllerContext.Controller.ValueProvider.GetValue(Name);
if (value != null)
      {
        return true;
      }
      return false;
This attribute class can then decorated on the respective action and the respective “Name” value can be provided. So if the submit is hitting this action and if the name matches of the HTML submit button name it then executes the action further or else it does not.

public class CustomerController : Controller
{
        [SubmitButtonSelector(Name="Save")]
        public ActionResult Save()
        {
            return Content("Save Called");
        }
        [SubmitButtonSelector(Name = "Delete")]
        public ActionResult Delete()
        {
            return Content("Delete Called");
        }
}

Watch Video:






Subscribe to get more Posts :