Keywords: ASP.NET MVC | Multiple Submit Buttons | C# | Form Submission | Model Binding
Abstract: This article explores techniques for handling multiple submit buttons in ASP.NET MVC forms, focusing on a custom attribute-based method and simpler approaches. It provides detailed code examples, implementation steps, and comparisons to help developers choose the best solution based on their needs, including security considerations and best practices.
Introduction
In ASP.NET MVC, when a single form contains multiple submit buttons, the framework typically routes all POST requests to the same controller action, which can lead to logic confusion. This article presents various effective methods to differentiate between button clicks and execute targeted business logic.
Attribute-Based Solution
A robust approach involves extending ActionNameSelectorAttribute with a custom attribute, allowing controller actions to be decorated for specific submit buttons. This method offers clear separation of concerns and high maintainability.
First, define the custom attribute class:
[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;
}
}In the Razor view, use button names formatted as "name:argument":
<form action="" method="post">
<input type="submit" value="Save" name="action:Save" />
<input type="submit" value="Cancel" name="action:Cancel" />
</form>Then, apply the attribute to corresponding controller actions:
[HttpPost]
[MultipleButton(Name = "action", Argument = "Save")]
public ActionResult Save(MessageModel mm) { ... }
[HttpPost]
[MultipleButton(Name = "action", Argument = "Cancel")]
public ActionResult Cancel(MessageModel mm) { ... }Simple Name-Value Method
An alternative method assigns the same name to all submit buttons and uses a switch statement in the controller to handle different values. This approach is straightforward and suitable for scenarios with few buttons and infrequent text changes.
In the view:
<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="submitButton" value="Send" />
<input type="submit" name="submitButton" value="Cancel" />
<% Html.EndForm(); %>In the controller:
public class MyController : Controller {
public ActionResult MyAction(string submitButton) {
switch(submitButton) {
case "Send":
return Send();
case "Cancel":
return Cancel();
default:
return View();
}
}
private ActionResult Send() { ... }
private ActionResult Cancel() { ... }
}HTML5 Attributes Method
Leveraging HTML5 formaction and formmethod attributes allows specifying different controller actions for each button. This method provides better separation but requires browser support for HTML5.
In the Razor view:
<input type="submit" name="response" value="Accept" formaction="@Url.Action("TermsAccept")" formmethod="post" class="btn btn-primary" />
<input type="submit" name="response" value="Decline" formaction="@Url.Action("TermsDecline")" formmethod="post" class="btn btn-default" />Then define separate controller actions:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult TermsAccept([Bind(Include = "UserID")] User user) { ... }
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult TermsDecline() { ... }Comparison and Selection
The attribute-based method is clean and scalable, ideal for complex scenarios; the simple name-value method is easy to implement but may become cumbersome with many buttons; the HTML5 method offers direct routing but depends on browser compatibility. Developers should choose based on project requirements such as maintainability, compatibility, and code simplicity.
Security Considerations
All methods should use [ValidateAntiForgeryToken] on controller actions and include @Html.AntiForgeryToken() in views to prevent CSRF attacks. Additionally, bind only necessary model properties to minimize the attack surface.
Conclusion
Handling multiple submit buttons in ASP.NET MVC can be achieved through various methods, with the custom attribute approach recommended for its elegance and flexibility, while simpler methods suffice for basic needs. Developers should consider factors like code maintainability and security when selecting a technique.