是否有一些简单的方法来处理来自同一个表单的多个提交按钮?例如:

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

知道如何在ASP中做到这一点吗?NET框架测试版?我在谷歌上搜索的所有例子中都有单个按钮。


当前回答

我的JQuery方法使用扩展方法:

public static MvcHtmlString SubmitButtonFor<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string value) where TController : Controller
{
    RouteValueDictionary routingValues = Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression(action);

    var onclick = string.Format("$('form').first().attr('action', '/{0}')", string.Join("/", routingValues.Values.ToArray().Where(x => x != null).Select(x => x.ToString()).ToArray()));
    var html = "<input type=\"submit\" value=\"" + value + "\" onclick=\"" + onclick + "\" />";

    return MvcHtmlString.Create(html);
}

你可以这样使用它:

@(Html.SubmitButtonFor<FooController>(c => c.Save(null), "Save"))

它是这样渲染的:

<input type="submit" value="Save" onclick="$('form').first().attr('action', '/Foo/Save')" >

其他回答

下面是基于Maarten Balliauw的帖子和评论,针对多个提交按钮问题的一个非常干净的基于属性的解决方案。

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

剃须刀:

<form action="" method="post">
 <input type="submit" value="Save" name="action:Save" />
 <input type="submit" value="Cancel" name="action:Cancel" />
</form>

和控制器:

[HttpPost]
[MultipleButton(Name = "action", Argument = "Save")]
public ActionResult Save(MessageModel mm) { ... }

[HttpPost]
[MultipleButton(Name = "action", Argument = "Cancel")]
public ActionResult Cancel(MessageModel mm) { ... }

更新:Razor页面提供相同的功能开箱即用。对于新的开发来说,它可能更可取。

你应该能够为按钮命名并赋予它们一个值;然后将此名称映射为操作的参数。或者,使用2个单独的动作链接或2个表单。

Eilon建议你可以这样做:

If you have more than one button you can distinguish between them by giving each button a name: <input type="submit" name="SaveButton" value="Save data" /> <input type="submit" name="CancelButton" value="Cancel and go back to main page" /> In your controller action method you can add parameters named after the HTML input tag names: public ActionResult DoSomeStuff(string saveButton, string cancelButton, ... other parameters ...) { ... } If any value gets posted to one of those parameters, that means that button was the one that got clicked. The web browser will only post a value for the one button that got clicked. All other values will be null. if (saveButton != null) { /* do save logic */ } if (cancelButton != null) { /* do cancel logic */ }

我喜欢这个方法,因为它不依赖于提交按钮的值属性,这个属性比分配的名称更有可能改变,并且不需要启用javascript

看到的: http://forums.asp.net/p/1369617/2865166.aspx#2865166

给你的提交按钮一个名字,然后在你的控制器方法中检查提交的值:

<% 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());
}
[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>

    }