How do you handle multiple submit buttons in ASP.NET MVC Framework?

后端 未结 30 2999
一个人的身影
一个人的身影 2020-11-21 07:16

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

<% Html.BeginForm(\"MyAction\", \"MyController\", FormMethod.Pos         


        
相关标签:
30条回答
  • 2020-11-21 07:45
    //model
        public class input_element
            {
             public string Btn { get; set; }
            }   
    
    //views--submit btn can be input type also...
        @using (Html.BeginForm())
        {
                <button type="submit" name="btn" value="verify">
                 Verify data</button>
                <button type="submit" name="btn" value="save">
                 Save data</button>    
                <button type="submit" name="btn" value="redirect">
                     Redirect</button>
        }
    
    //controller
    
        public ActionResult About()
            {
                ViewBag.Message = "Your app description page.";
                return View();
            }
    
            [HttpPost]
            public ActionResult About(input_element model)
            {
                    if (model.Btn == "verify")
                    {
                    // the Verify button was clicked
                    }
                    else if (model.Btn == "save")
                    {
                    // the Save button was clicked
                    } 
                    else if (model.Btn == "redirect")
                    {
                    // the Redirect button was clicked
                    } 
                    return View();
            }
    
    0 讨论(0)
  • 2020-11-21 07:46

    Just written a post about that: Multiple submit buttons with ASP.NET MVC:

    Basically, instead of using ActionMethodSelectorAttribute, I am using ActionNameSelectorAttribute, which allows me to pretend the action name is whatever I want it to be. Fortunately, ActionNameSelectorAttribute does not just make me specify action name, instead I can choose whether the current action matches request.

    So there is my class (btw I am not too fond of the name):

    public class HttpParamActionAttribute : ActionNameSelectorAttribute {
        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
            if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
                return true;
    
            if (!actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
                return false;
    
            var request = controllerContext.RequestContext.HttpContext.Request;
            return request[methodInfo.Name] != null;
        }
    } 
    

    To use just define a form like this:

    <% using (Html.BeginForm("Action", "Post")) { %>
      <!— …form fields… -->
      <input type="submit" name="saveDraft" value="Save Draft" />
      <input type="submit" name="publish" value="Publish" />
    <% } %> 
    

    and controller with two methods

    public class PostController : Controller {
        [HttpParamAction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult SaveDraft(…) {
            //…
        }
    
        [HttpParamAction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Publish(…) {
            //…
        } 
    }
    

    As you see, the attribute does not require you to specify anything at all. Also, name of the buttons are translated directly to the method names. Additionally (I haven’t tried that) these should work as normal actions as well, so you can post to any of them directly.

    0 讨论(0)
  • 2020-11-21 07:46
    [HttpPost]
    public ActionResult ConfirmMobile(string nameValueResend, string nameValueSubmit, RegisterModel model)
        {
            var button = nameValueResend ?? nameValueSubmit;
            if (button == "Resend")
            {
    
            }
            else
            {
    
            }
        }
    
    
        Razor file Content:
        @using (Html.BeginForm()
        {
            <div class="page registration-result-page">
    
                <div class="page-title">
                    <h1> Confirm Mobile Number</h1>
                </div>
    
                <div class="result">
                    @Html.EditorFor(model => model.VefificationCode)
                    @Html.LabelFor(model => model.VefificationCode, new { })
                    @Html.ValidationMessageFor(model => model.VefificationCode)
                </div>
                <div class="buttons">
                    <button type="submit" class="btn" name="nameValueResend" value="Resend">
                        Resend
                    </button>
                    <button type="submit" class="btn" name="nameValueSubmit" value="Verify">
                        Submit
                    </button>
    
                </div>
                </div>
    
        }
    
    0 讨论(0)
  • 2020-11-21 07:47

    it is short and suite:

    It was answered by Jeroen Dop

    <input type="submit" name="submitbutton1" value="submit1" />
    <input type="submit" name="submitbutton2" value="submit2" />
    

    and do like this in code behinde

     if( Request.Form["submitbutton1"] != null)
    {
        // Code for function 1
    }
    else if(Request.Form["submitButton2"] != null )
    {
           // code for function 2
    }
    

    Good luck.

    0 讨论(0)
  • 2020-11-21 07:47

    Something I don't like about ActionSelectName is that IsValidName is called for every action method in the controller; I don't know why it works this way. I like a solution where every button has a different name based on what it does, but I don't like the fact that you have to have as many parameters in the action method as buttons in the form. I have created an enum for all button types:

    public enum ButtonType
    {
        Submit,
        Cancel,
        Delete
    }
    

    Instead of ActionSelectName, I use an ActionFilter:

    public class MultipleButtonsEnumAttribute : ActionFilterAttribute
    {
        public Type EnumType { get; set; }
    
        public MultipleButtonsEnumAttribute(Type enumType)
        {
            EnumType = enumType;
        }
    
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            foreach (var key in filterContext.HttpContext.Request.Form.AllKeys)
            {
                if (Enum.IsDefined(EnumType, key))
                {
                    var pDesc = filterContext.ActionDescriptor.GetParameters()
                        .FirstOrDefault(x => x.ParameterType == EnumType);
                    filterContext.ActionParameters[pDesc.ParameterName] = Enum.Parse(EnumType, key);
                    break;
                }
            }
        }
    }
    

    The filter will find the button name in the form data and if the button name matches any of the button types defined in the enum, it will find the ButtonType parameter among the action parameters:

    [MultipleButtonsEnumAttribute(typeof(ButtonType))]
    public ActionResult Manage(ButtonType buttonPressed, ManageViewModel model)
    {
        if (button == ButtonType.Cancel)
        {
            return RedirectToAction("Index", "Home");
        }
        //and so on
        return View(model)
    }
    

    and then in views, I can use:

    <input type="submit" value="Button Cancel" name="@ButtonType.Cancel" />
    <input type="submit" value="Button Submit" name="@ButtonType.Submit" />
    
    0 讨论(0)
  • 2020-11-21 07:47

    I've came across this 'problem' as well but found a rather logical solution by adding the name attribute. I couldn't recall having this problem in other languages.

    http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

    • ...
    • If a form contains more than one submit button, only the activated submit button is successful.
    • ...

    Meaning the following code value attributes can be changed, localized, internationalized without the need for extra code checking strongly-typed resources files or constants.

    <% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
    <input type="submit" name="send" value="Send" />
    <input type="submit" name="cancel" value="Cancel" />
    <input type="submit" name="draft" value="Save as draft" />
    <% Html.EndForm(); %>`
    

    On the receiving end you would only need to check if any of your known submit types isn't null

    public ActionResult YourAction(YourModel model) {
    
        if(Request["send"] != null) {
    
            // we got a send
    
        }else if(Request["cancel"]) {
    
            // we got a cancel, but would you really want to post data for this?
    
        }else if(Request["draft"]) {
    
            // we got a draft
    
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题