html - आप एएसपी.नेट एमवीसी फ्रेमवर्क में एकाधिक सबमिट बटन कैसे संभालते हैं?




asp.net asp.net-mvc (20)

अगर आपके पास एचटीएमएल 5 के उपयोग पर प्रतिबंध नहीं हैं, तो आप formaction साथ <button> टैग का उपयोग कर सकते हैं विशेषता:

<form action="demo_form.asp" method="get">
   First name: <input type="text" name="fname" /><br />
   Last name: <input type="text" name="lname" /><br />
   <button type="submit">Submit</button><br />
   <button type="submit" formaction="demo_admin.asp">Submit as admin</button>
</form>

संदर्भ: http://www.w3schools.com/html5/att_button_formaction.asp

क्या एक ही फॉर्म से एकाधिक सबमिट बटन को संभालने का कोई आसान तरीका है? उदाहरण:

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

एएसपी.NET फ्रेमवर्क बीटा में ऐसा करने का कोई विचार है? उन सभी उदाहरणों के लिए जिन्हें मैंने गुम किया है उनमें एकल बटन हैं।


अपने सबमिट बटन को एक नाम दें, और फिर अपने नियंत्रक विधि में सबमिट किए गए मान का निरीक्षण करें:

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

पोस्टिंग

public class MyController : Controller {
    public ActionResult MyAction(string submitButton) {
        switch(submitButton) {
            case "Send":
                // delegate sending to another controller action
                return(Send());
            case "Cancel":
                // call another action to perform the cancellation
                return(Cancel());
            default:
                // If they've submitted the form without a submitButton, 
                // just return the view again.
                return(View());
        }
    }

    private ActionResult Cancel() {
        // process the cancellation request here.
        return(View("Cancelled"));
    }

    private ActionResult Send() {
        // perform the actual send operation here.
        return(View("SendConfirmed"));
    }

}

संपादित करें:

स्थानीयकृत साइटों के साथ काम करने के लिए इस दृष्टिकोण को विस्तारित करने के लिए, अपने संदेशों को कहीं और अलग करें (उदाहरण के लिए एक संसाधन फ़ाइल को दृढ़ता से टाइप की गई संसाधन कक्षा में संकलित करना)

फिर कोड को संशोधित करें ताकि यह इस प्रकार काम करे:

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

और आपका नियंत्रक इस तरह दिखना चाहिए:

// Note that the localized resources aren't constants, so 
// we can't use a switch statement.

if (submitButton == Resources.Messages.Send) { 
    // delegate sending to another controller action
    return(Send());

} else if (submitButton == Resources.Messages.Cancel) {
     // call another action to perform the cancellation
     return(Cancel());
}

आपको बटनों का नाम देने और उन्हें एक मूल्य देने में सक्षम होना चाहिए; फिर कार्रवाई के लिए तर्क के रूप में इस नाम को मानचित्र करें। वैकल्पिक रूप से, 2 अलग-अलग क्रिया-लिंक या 2 रूपों का उपयोग करें।


एइलन सुझाव देता है कि आप इसे इस तरह कर सकते हैं:

यदि आपके पास एक से अधिक बटन हैं तो आप प्रत्येक बटन को एक नाम देकर उनके बीच अंतर कर सकते हैं:

<input type="submit" name="SaveButton" value="Save data" />
<input type="submit" name="CancelButton" value="Cancel and go back to main page" />

आपके कंट्रोलर एक्शन विधि में आप HTML इनपुट टैग नामों के नाम पर पैरामीटर जोड़ सकते हैं:

public ActionResult DoSomeStuff(string saveButton, string
cancelButton, ... other parameters ...)
{ ... }

यदि कोई मान उन मानकों में से किसी एक पर पोस्ट हो जाता है, तो इसका मतलब है कि वह बटन क्लिक किया गया था। वेब ब्राउज़र केवल एक बटन के लिए एक मूल्य पोस्ट करेगा जो क्लिक किया गया था। अन्य सभी मूल्य शून्य होंगे।

if (saveButton != null) { /* do save logic */ }
if (cancelButton != null) { /* do cancel logic */ }

मुझे इस विधि को पसंद है क्योंकि यह सबमिट बटन की वैल्यू प्रॉपर्टी पर निर्भर नहीं है जो असाइन किए गए नामों से बदलने की अधिक संभावना है और जावास्क्रिप्ट को सक्षम करने की आवश्यकता नहीं है

देखें: http://forums.asp.net/p/1369617/2865166.aspx#2865166


जैसा कि उल्लेख किया गया है, आप कार्रवाई में नाम की जांच कर सकते हैं, लेकिन आप यह विचार कर सकते हैं कि यह अच्छा डिज़ाइन है या नहीं। कार्रवाई की ज़िम्मेदारी पर विचार करना एक अच्छा विचार है और यूआई पहलुओं जैसे बटन नामों के लिए यह डिज़ाइन बहुत अधिक नहीं है। तो 2 रूपों और 2 कार्यों का उपयोग करने पर विचार करें:

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

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

साथ ही, "रद्द करें" के मामले में, आप आमतौर पर फॉर्म को संसाधित नहीं कर रहे हैं और एक नए यूआरएल पर जा रहे हैं। इस मामले में आपको फॉर्म जमा करने की आवश्यकता नहीं है और केवल एक लिंक की आवश्यकता है:

<%=Html.ActionLink("Cancel", "List", "MyController") %>

डेविड फाइंडली ने अपने एएसपी.Net वेबलॉग पर ऐसा करने के लिए आपके पास 3 अलग-अलग विकल्पों को लिखा है।

अपने समाधान, और प्रत्येक के फायदे और नुकसान देखने के लिए लेख को एक ही रूप में कई बटन पढ़ें। आईएमएचओ वह एक बहुत ही सुरुचिपूर्ण समाधान प्रदान करता है जो आपके द्वारा अपनी क्रिया को सजाने वाले गुणों का उपयोग करता है।


मुझे एक्शनसेलेनामनाम के बारे में कुछ पसंद नहीं है कि IsValidName को नियंत्रक में प्रत्येक क्रिया विधि के लिए बुलाया जाता है; मुझे नहीं पता कि यह इस तरह क्यों काम करता है। मुझे एक समाधान पसंद है जहां प्रत्येक बटन के पास एक अलग नाम होता है जो यह करता है, लेकिन मुझे यह तथ्य पसंद नहीं है कि आपके पास फॉर्म में बटन के रूप में एक्शन विधि में कई पैरामीटर हैं। मैंने सभी बटन प्रकारों के लिए एक enum बनाया है:

public enum ButtonType
{
    Submit,
    Cancel,
    Delete
}

ActionSelectName के बजाय, मैं एक एक्शनफ़िल्टर का उपयोग करता हूं:

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

फ़िल्टर को फॉर्म डेटा में बटन का नाम मिलेगा और यदि बटन नाम एनम में परिभाषित किसी भी बटन प्रकार से मेल खाता है, तो उसे बटन पैरामीटर पैरामीटर एक्शन पैरामीटर के बीच मिलेगा:

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

और फिर विचारों में, मैं इसका उपयोग कर सकता हूं:

<input type="submit" value="Button Cancel" name="@ButtonType.Cancel" />
<input type="submit" value="Button Submit" name="@ButtonType.Submit" />

मेरे पास सही जगह पर टिप्पणी करने के लिए पर्याप्त प्रतिनिधि नहीं है, लेकिन मैंने इस दिन पूरे दिन बिताया ताकि साझा करना चाहें।

"एकाधिक ValueProvider.GetValue(keyValue) " समाधान को लागू करने का प्रयास करते समय ValueProvider.GetValue(keyValue) गलत तरीके से वापस आ जाएगा।

यह पता चला कि मैं System.Web.MVC संस्करण 3.0 का संदर्भ दे रहा था जब यह 4.0 होना चाहिए (अन्य असेंबली 4.0 हैं)। मुझे नहीं पता कि मेरी परियोजना सही तरीके से अपग्रेड क्यों नहीं हुई और मुझे कोई और स्पष्ट समस्या नहीं थी।

तो यदि आपका ActionNameSelectorAttribute काम नहीं कर रहा है ... उसे जांचें।


मैं सुझाव दूंगा कि इच्छुक पार्टियों को मार्टिन बल्लियाव के समाधान पर नजर डालें । मुझे लगता है कि यह बहुत ही सुरुचिपूर्ण है।

यदि लिंक गायब हो जाता है, तो यह एक बटन नियंत्रक पर लागू MultiButton विशेषता का उपयोग कर रहा है यह इंगित करने के लिए कि कौन सा बटन उस क्रिया को क्लिक करना चाहिए।


मैंने सभी समाधानों का संश्लेषण करने की कोशिश की है और एक [ButtenHandler] विशेषता बनाई है जो फ़ॉर्म पर एकाधिक बटन को संभालना आसान बनाता है।

मैंने इसे एएसपी.नेट एमवीसी में कोडप्रोजेक्ट एकाधिक पैरामीटर (लोकलाइज करने योग्य) फॉर्म बटन पर वर्णित किया है।

इस बटन के साधारण मामले को संभालने के लिए:

<button type="submit" name="AddDepartment">Add Department</button>

आपके पास निम्न कार्यवाही विधि की तरह कुछ होगा:

[ButtonHandler()]
public ActionResult AddDepartment(Company model)
{
    model.Departments.Add(new Department());
    return View(model);
}

ध्यान दें कि बटन का नाम क्रिया विधि के नाम से कैसे मेल खाता है। लेख में यह भी बताया गया है कि इंडेक्स के साथ मूल्यों और बटन के साथ बटन कैसे हैं।


यह छोटा और सूट है:

जेरोनी डोप ने इसका उत्तर दिया

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

और कोड पीछे में ऐसा करते हैं

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

सौभाग्य।


यह वह तकनीक है जिसका मैं उपयोग करता हूं और मैं इसे अभी तक नहीं देखता हूं। लिंक (साजिद इस्माइल द्वारा पोस्ट किया गया) जो इस समाधान को प्रेरित करता है http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form .aspx )। यह किसी भी समस्या के बिना स्थानीयकरण करने के लिए डिलन बीट्टी के जवाब को अपनाना है।

दृश्य में:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<button name="button" value="send"><%: Resources.Messages.Send %></button>
<button name="button" value="cancel"><%: Resources.Messages.Cancel %></button>
<% Html.EndForm(); %>

नियंत्रक में:

public class MyController : Controller 
{
    public ActionResult MyAction(string button)
    {
         switch(button)
         {
             case "send":
                 this.DoSend();
                 break;
             case "cancel":
                 this.DoCancel();
                 break;
         }
    }
}

यहां एक विस्तार विधि है जिसे मैंने एकाधिक छवि और / या टेक्स्ट बटन को संभालने के लिए लिखा था।

छवि बटन के लिए यहां HTML है:

<input id="btnJoin" name="Join" src="/content/images/buttons/btnJoin.png" 
       type="image">

या एक पाठ सबमिट बटन के लिए:

<input type="submit" class="ui-button green" name="Submit_Join" value="Add to cart"  />
<input type="submit" class="ui-button red" name="Submit_Skip" value="Not today"  />

यहां एक्सटेंशन विधि है जिसे आप नियंत्रक से form.GetSubmitButtonName() साथ कॉल करते हैं। form.GetSubmitButtonName() । छवि बटन के लिए यह .x साथ एक फॉर्म पैरामीटर की तलाश करता है (जो इंगित करता है कि एक छवि बटन क्लिक किया गया था) और नाम निकालता है। नियमित input बटन के लिए यह Submit_ साथ शुरू होने वाला नाम Submit_ और बाद में आदेश निकालता है। क्योंकि मैं 'कमांड' निर्धारित करने के तर्क को दूर कर रहा हूं, आप सर्वर साइड कोड को बदले बिना क्लाइंट पर छवि + टेक्स्ट बटन के बीच स्विच कर सकते हैं।

public static class FormCollectionExtensions
{
    public static string GetSubmitButtonName(this FormCollection formCollection)
    {
        return GetSubmitButtonName(formCollection, true);
    }

    public static string GetSubmitButtonName(this FormCollection formCollection, bool throwOnError)
    {
        var imageButton = formCollection.Keys.OfType<string>().Where(x => x.EndsWith(".x")).SingleOrDefault();
        var textButton = formCollection.Keys.OfType<string>().Where(x => x.StartsWith("Submit_")).SingleOrDefault();

        if (textButton != null)
        {
            return textButton.Substring("Submit_".Length);
        }

        // we got something like AddToCart.x
        if (imageButton != null)
        {
            return imageButton.Substring(0, imageButton.Length - 2);
        }

        if (throwOnError)
        {
            throw new ApplicationException("No button found");
        }
        else
        {
            return null;
        }
    }
}

नोट: टेक्स्ट बटन के लिए आपको Submit_ साथ नाम उपसर्ग करना Submit_ । मैं इस तरह से पसंद करता हूं क्योंकि इसका मतलब है कि आप कोड को बदलने के बिना टेक्स्ट (डिस्प्ले) मान बदल सकते हैं। SELECT तत्वों के विपरीत, एक INPUT बटन में केवल 'मान' होता है और कोई अलग 'टेक्स्ट' विशेषता नहीं होती है। मेरे बटन अलग-अलग संदर्भों के तहत अलग-अलग चीजें कहते हैं - लेकिन उसी 'कमांड' पर नक्शा लगाएं। मैं == "Add to cart" के लिए कोड होने से इस तरह नाम निकालने को पसंद करता हूं।


यहां मेरे लिए सबसे अच्छा काम करता है:

<input type="submit" value="Delete" name="onDelete" />
<input type="submit" value="Save" name="onSave" />


public ActionResult Practice(MyModel model, string onSave, string onDelete)
{
    if (onDelete != null)
    {
        // Delete the object
        ...
        return EmptyResult();
    }

    // Save the object
    ...
    return EmptyResult();
}

Based on mkozicki answer I come up with a bit different solution. I still use ActionNameSelectorAttribute But I needed to handle two buttons 'Save' and 'Sync'. They do almost the same so I didn't want to have two actions.

attribute :

public class MultipleButtonActionAttribute : ActionNameSelectorAttribute
{        
    private readonly List<string> AcceptedButtonNames;

    public MultipleButtonActionAttribute(params string[] acceptedButtonNames)
    {
        AcceptedButtonNames = acceptedButtonNames.ToList();
    }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {            
        foreach (var acceptedButtonName in AcceptedButtonNames)
        {
            var button = controllerContext.Controller.ValueProvider.GetValue(acceptedButtonName);
            if (button == null)
            {
                continue;
            }                
            controllerContext.Controller.ControllerContext.RouteData.Values.Add("ButtonName", acceptedButtonName);
            return true;
        }
        return false;
    }
}

view

<input type="submit" value="Save" name="Save" />
<input type="submit" value="Save and Sync" name="Sync" />

controller

 [MultipleButtonAction("Save", "Sync")]
 public ActionResult Sync(OrgSynchronizationEditModel model)
 {
     var btn = this.RouteData.Values["ButtonName"];

I also want to point out that if actions do different things I would probably follow mkozicki post.


For each submit button just add:

$('#btnSelector').click(function () {

    $('form').attr('action', "/Your/Action/);
    $('form').submit();

});

I've created an ActionButton method for the HtmlHelper . It will generate normal input button with a bit of javascript in the OnClick event that will submit the form to the specified Controller/Action.

You use the helper like that

@Html.ActionButton("MyControllerName", "MyActionName", "button text")

this will generate the following HTML

<input type="button" value="button text" onclick="this.form.action = '/MyWebsiteFolder/MyControllerName/MyActionName'; this.form.submit();">

Here is the extension method code:

VB.Net

<System.Runtime.CompilerServices.Extension()>
Function ActionButton(pHtml As HtmlHelper, pAction As String, pController As String, pRouteValues As Object, pBtnValue As String, pBtnName As String, pBtnID As String) As MvcHtmlString
    Dim urlHelperForActionLink As UrlHelper
    Dim btnTagBuilder As TagBuilder

    Dim actionLink As String
    Dim onClickEventJavascript As String

    urlHelperForActionLink = New UrlHelper(pHtml.ViewContext.RequestContext)
    If pController <> "" Then
        actionLink = urlHelperForActionLink.Action(pAction, pController, pRouteValues)
    Else
        actionLink = urlHelperForActionLink.Action(pAction, pRouteValues)
    End If
    onClickEventJavascript = "this.form.action = '" & actionLink & "'; this.form.submit();"

    btnTagBuilder = New TagBuilder("input")
    btnTagBuilder.MergeAttribute("type", "button")

    btnTagBuilder.MergeAttribute("onClick", onClickEventJavascript)

    If pBtnValue <> "" Then btnTagBuilder.MergeAttribute("value", pBtnValue)
    If pBtnName <> "" Then btnTagBuilder.MergeAttribute("name", pBtnName)
    If pBtnID <> "" Then btnTagBuilder.MergeAttribute("id", pBtnID)

    Return MvcHtmlString.Create(btnTagBuilder.ToString(TagRenderMode.Normal))
End Function

C# (the C# code is just decompiled from the VB DLL, so it can get some beautification... but time is so short :-))

public static MvcHtmlString ActionButton(this HtmlHelper pHtml, string pAction, string pController, object pRouteValues, string pBtnValue, string pBtnName, string pBtnID)
{
    UrlHelper urlHelperForActionLink = new UrlHelper(pHtml.ViewContext.RequestContext);
    bool flag = Operators.CompareString(pController, "", true) != 0;
    string actionLink;
    if (flag)
    {
        actionLink = urlHelperForActionLink.Action(pAction, pController, System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(pRouteValues));
    }
    else
    {
        actionLink = urlHelperForActionLink.Action(pAction, System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(pRouteValues));
    }
    string onClickEventJavascript = "this.form.action = '" + actionLink + "'; this.form.submit();";
    TagBuilder btnTagBuilder = new TagBuilder("input");
    btnTagBuilder.MergeAttribute("type", "button");
    btnTagBuilder.MergeAttribute("onClick", onClickEventJavascript);
    flag = (Operators.CompareString(pBtnValue, "", true) != 0);
    if (flag)
    {
        btnTagBuilder.MergeAttribute("value", pBtnValue);
    }
    flag = (Operators.CompareString(pBtnName, "", true) != 0);
    if (flag)
    {
        btnTagBuilder.MergeAttribute("name", pBtnName);
    }
    flag = (Operators.CompareString(pBtnID, "", true) != 0);
    if (flag)
    {
        btnTagBuilder.MergeAttribute("id", pBtnID);
    }
    return MvcHtmlString.Create(btnTagBuilder.ToString(TagRenderMode.Normal));
}

These methods have various parameters, but for the ease of use you can create some overload that take just the parameters you need.


Modified version of HttpParamActionAttribute method but with a bug fix for not causing an error on expired/invalid session postbacks. To see if this is a problem with your current site, open the your form in a window and just before you go to click Save or Publish , open a duplicate window, and logout. Now go back to your first window and try to submit your form using either button. For me I got an error so this change solves that problem for me. I omit a bunch of stuff for the sake of brevity but you should get the idea. The key parts are the inclusion of ActionName on the attribute and making sure the name passed in is the name of the View that shows the form

Attribute Class

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class HttpParamActionAttribute : ActionNameSelectorAttribute
{
    private readonly string actionName;

    public HttpParamActionAttribute(string actionName)
    {
        this.actionName = actionName;
    }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
            return true;

        if (!actionName.Equals(this.actionName, StringComparison.InvariantCultureIgnoreCase))
            return false;

        var request = controllerContext.RequestContext.HttpContext.Request;
        return request[methodInfo.Name] != null;
    }
}

Controller

[Authorize(Roles="CanAddContent")]
public ActionResult CreateContent(Guid contentOwnerId)
{
    var viewModel = new ContentViewModel
    {
        ContentOwnerId = contentOwnerId
        //populate rest of view model
    }
    return View("CreateContent", viewModel);
}

[Authorize(Roles="CanAddContent"), HttpPost, HttpParamAction("CreateContent"), ValidateAntiForgeryToken]
public ActionResult SaveDraft(ContentFormModel model)
{
    //Save as draft
    return RedirectToAction("CreateContent");
}

[Authorize(Roles="CanAddContent"), HttpPost, HttpParamAction("CreateContent"), ValidateAntiForgeryToken]
public ActionResult Publish(ContentFormModel model)
{
    //publish content
    return RedirectToAction("CreateContent");
}

राय

@using (Ajax.BeginForm("CreateContent", "MyController", new { contentOwnerId = Model.ContentOwnerId }))
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(x => x.ContentOwnerId)

    <!-- Rest of your form controls -->
    <input name="SaveDraft" type="submit" value="SaveDraft" />
    <input name="Publish" type="submit" value="Publish" />
}

When using ajax forms, we can use ActionLinks with POST HttpMethod and serialize the form in the AjaxOptions.OnBegin event.

Let's say you have two actions, InsertAction and UpdateAction:

<form>
    @Html.Hidden("SomeField", "SomeValue")

    @Ajax.ActionLink(
        "Insert",
        "InsertAction",
        null,
        new AjaxOptions { 
            OnBegin = "OnBegin", 
            UpdateTargetId = "yourDiv", 
            HttpMethod = "POST" })
    @Ajax.ActionLink(
        "Update",
        "UpdateAction",
        null,
        new AjaxOptions { 
            OnBegin = "OnBegin", 
            UpdateTargetId = "yourDiv", 
            HttpMethod = "POST" })
</form>

Javascript

function OnBegin(xhr, settings) {
    settings.data = $("form").serialize();
}

this is the best way that i have found:

http://iwayneo.blogspot.co.uk/2013/10/aspnet-mvc-action-selector-with-list.html

यहां कोड है:

    /// <summary>
    /// ActionMethodSelector to enable submit buttons to execute specific action methods.
    /// </summary>
    public class AcceptParameterAttribute : ActionMethodSelectorAttribute
   {
        /// <summary>
        /// Gets or sets the value to use to inject the index into
        /// </summary>
       public string TargetArgument { get; set; }

       /// <summary>
       /// Gets or sets the value to use in submit button to identify which method to select. This must be unique in each controller.
       /// </summary>
       public string Action { get; set; }

       /// <summary>
       /// Gets or sets the regular expression to match the action.
       /// </summary>
       public string ActionRegex { get; set; }

       /// <summary>
       /// Determines whether the action method selection is valid for the specified controller context.
       /// </summary>
       /// <param name="controllerContext">The controller context.</param>
       /// <param name="methodInfo">Information about the action method.</param>
       /// <returns>true if the action method selection is valid for the specified controller context; otherwise, false.</returns>
       public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
       {

           if (controllerContext == null)
           {
               throw new ArgumentNullException("controllerContext");
           }

           Func<NameValueCollection> formGetter;
           Func<NameValueCollection> queryStringGetter;

           ValidationUtility.GetUnvalidatedCollections(HttpContext.Current, out formGetter, out queryStringGetter);

           var form = formGetter();
           var queryString = queryStringGetter();

           var req = form.AllKeys.Any() ? form : queryString;

           if (!string.IsNullOrEmpty(this.ActionRegex))
           {
               foreach (var key in req.AllKeys.Where(k => k.StartsWith(Action, true, System.Threading.Thread.CurrentThread.CurrentCulture)))
               {
                   if (key.Contains(":"))
                   {
                       if (key.Split(':').Count() == this.ActionRegex.Split(':').Count())
                       {
                           bool match = false;
                           for (int i = 0; i < key.Split(':').Count(); i++)
                           {
                               if (Regex.IsMatch(key.Split(':')[0], this.ActionRegex.Split(':')[0]))
                               {
                                   match = true;
                               }
                               else
                               {
                                   match = false;
                                   break;
                               }
                           }

                           if (match)
                           {
                               return !string.IsNullOrEmpty(req[key]);
                           }
                       }
                   }
                   else
                   {
                       if (Regex.IsMatch(key, this.Action + this.ActionRegex))
                       {
                           return !string.IsNullOrEmpty(req[key]);
                       }
                   }

               }
               return false;
           }
           else
           {
               return req.AllKeys.Contains(this.Action);
           }
       }
   }

Enjoy a code-smell-less multi submit button future.

धन्यवाद







form-submit