Search This Blog

Thursday, March 17, 2016

MVC Handling multiple submit buttons in single view


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);
        }}

Popular Posts