MVC: Handling Multiple
button submission from one view
While developing any web applications we use to
design lot more forms. Most of the times a form perform a single action,
posting data to some controller. There is no necessity that each of the form
will contain only a single submit button. Sometimes, we may need a form which
will contain multiple submit buttons. As in the following case
<h2>SignUp</h2>
@using (Html.BeginForm("PostData","Home",
FormMethod.Post))
{
@Html.AntiForgeryToken()
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="username">Username:</label>
@Html.TextBox("username")
</p>
<p>
<label for="email">Email:</label>
@Html.TextBox("email")
</p>
<p>
<label for="password">Password:</label>
@Html.TextBox("password")
</p>
<p>
<label for="confirmPassword">Confirm Password:</label>
@Html.TextBox("confirmPassword")
</p>
<p>
<input type="submit" name="btnRegister" id="btnRegister" value="register" />
<input type="submit" name="btnCancel" id="btnCancel" value="Cancel" />
</p>
</fieldset>
</div>
}
So in this case,
our form will be posting data to a single action PostData but it contains 2 different submit
button. So to handle this scenario, we need to code something like this
in our controller.
// handling multiple buttons post by using if else conditions
[HttpPost]
public
ActionResult PostData(string btnRegister, string btnCancel)
{
string
buttonName = btnRegister ?? btnCancel;
if (!string.IsNullOrEmpty(btnRegister))
{ //write code related to Register
}
else if (!string.IsNullOrEmpty(btnCancel))
{ //write code related to Cancel
}
return
Content("button name: " + buttonName);
}
Also this looks very simple when we have a simple Action, think how about doing this on a form of 10 fields & 4 buttons.
How if I am able to specify the name of the button near the action method wherein I will specify the name of the button on which that action needs to be invoked. We can achieve this in Asp.Net MVC by using the ActionMethodSelectorAttribute attribute. Here is a code snippet to show the use of the attribute.
public class AcceptParameterAttribute : ActionMethodSelectorAttribute
{
public
string
Name { get; set; }
public
string
Value { get; set; }
public
override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo
methodInfo)
{
var req =
controllerContext.RequestContext.HttpContext.Request;
return
req[this.Name] == this.Value;
}
}The ActionMethodSelectorAttribute is executed before the Action is executed, so we here we can check which button is clicked while submitting the form using the Form NameValueCollection object on the IsValidForRequest event of the ActionMethodSelectorAttribute.
This attribute will also help preventing the JavaScript attacks as this will only accept the values submitted by the specific submit button.
public class HomeController
: Controller {
// handling multiple buttons post by using ActionMethodSelectorAttribute
[HttpPost]
[ActionName("PostData")]
[AcceptParameter(Name
= "btnRegister", Value = "register")]
public
ActionResult PostbtnRegister(string username, string email, string password, string confirmPassword)
{
return
Content("you clicked
reset" + username + email +
password + confirmPassword);
}
[HttpPost]
[ActionName("PostData")]
[AcceptParameter(Name
= "btnCancel", Value = "Cancel")]
public
ActionResult PostbtnCancel(string username, string email, string password, string
confirmPassword)
{
return
Content("you clicked
Cancel" + username + email +
password + confirmPassword);
}}