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

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

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


当前回答

以下是最适合我的方法:

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

其他回答

你可以这样写:

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

然后在页面中检查name == "Send"或者name == "Cancel"…

这个脚本允许指定一个data-form-action属性,它将在所有浏览器中作为HTML5 formaction属性(以一种不引人注目的方式):

$(document).on('click', '[type="submit"][data-form-action]', function(event) {
    var $this = $(this),
    var formAction = $this.attr('data-form-action'),
    $form = $($this.closest('form'));
    $form.attr('action', formAction);             
});

包含按钮的表单将被发送到data-form-action属性中指定的URL:

<button type="submit" data-form-action="different/url">Submit</button>   

这需要jQuery 1.7。对于以前的版本,您应该使用live()而不是on()。

我来派对已经很晚了,但现在开始… 我的实现借用了@mkozicki,但需要更少的硬编码字符串来出错。需要4.5+框架。实际上,控制器方法名应该是路由的关键。

标记。按钮名称必须以“action:[controllerMethodName]”为键

(注意使用c# 6的API名称,提供了对希望调用的控制器方法名称的特定类型引用。

<form>
    ... form fields ....
    <button name="action:@nameof(MyApp.Controllers.MyController.FundDeathStar)" type="submit" formmethod="post">Fund Death Star</button>
    <button name="action:@nameof(MyApp.Controllers.MyController.HireBoba)" type="submit" formmethod="post">Hire Boba Fett</button>
</form>

控制器:

namespace MyApp.Controllers
{
    class MyController
    {    
        [SubmitActionToThisMethod]
        public async Task<ActionResult> FundDeathStar(ImperialModel model)
        {
            await TrainStormTroopers();
            return View();
        }

        [SubmitActionToThisMethod]
        public async Task<ActionResult> HireBoba(ImperialModel model)
        {
            await RepairSlave1();
            return View();
        }
    }
}

属性的魔法。注意使用CallerMemberName功能。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class SubmitActionToThisMethodAttribute : ActionNameSelectorAttribute
{        
    public SubmitActionToThisMethodAttribute([CallerMemberName]string ControllerMethodName = "")
    {
        controllerMethod = ControllerMethodName;
        actionFormat = string.Concat(actionConstant, ":", controllerMethod);
    }
    const string actionConstant = "action";
    readonly string actionFormat;
    readonly string controllerMethod;

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        var isValidName = false;
        var value = controllerContext.Controller.ValueProvider.GetValue(actionFormat);

        if (value != null)
        {
            controllerContext.Controller.ControllerContext.RouteData.Values[actionConstant] = controllerMethod;
            isValidName = true;
        }
        return isValidName;
    }
}

有三种方法可以解决上述问题

HTML的方式 Jquery的方式 “ActionNameSelectorAttribute”的方式

下面是一个视频,它以演示的方式总结了所有三种方法。

https://www.facebook.com/shivprasad.koirala/videos/vb.100002224977742/809335512483940

HTML方式:-

在HTML中,我们需要创建两个表单,并在每个表单中放置“Submit”按钮。每一种形式的动作都会指向不同的/各自的动作。你可以看到下面的代码,第一个表单发布到“Action1”,第二个表单将发布到“Action2”,这取决于点击哪个“提交”按钮。

<form action="Action1" method=post>
<input type=”submit” name=”Submit1”/>
</form>

<form action="Action2" method=post>
<input type=”submit” name=”Submit2”>
</form>

Ajax方式:-

如果您是Ajax爱好者,那么第二个选项会让您更兴奋。在Ajax中,我们可以创建两个不同的函数“Fun1”和“Fun1”,参见下面的代码。这些函数将使用JQUERY或任何其他框架进行Ajax调用。这些函数都与“Submit”按钮的“OnClick”事件绑定。每个函数都调用各自的动作名。

<Script language="javascript">
function Fun1()
{
$.post(“/Action1”,null,CallBack1);
}
function Fun2()
{
$.post(“/Action2”,null,CallBack2);
}
</Script>

<form action="/Action1" method=post>
<input type=submit name=sub1 onclick=”Fun2()”/>
</form>
<form action="/Action2" method=post>
<input type=submit name=sub2 onclick=”Fun1()”/>
</form>

使用“ActionNameSelectorAttribute”:-

这是一个很好的干净的选择。“ActionNameSelectorAttribute”是一个简单的属性类,我们可以在其中编写决策逻辑,该逻辑将决定可以执行哪些操作。

首先在HTML中,我们需要给提交按钮设置正确的名称以便在服务器上识别它们。

你可以看到我们把“保存”和“删除”放在按钮名称上。你还可以注意到,在动作中,我们只是把控制器名“Customer”,而不是一个特定的动作名。我们期望动作名称将由“ActionNameSelectorAttribute”决定。

<form action=”Customer” method=post>
<input type=submit value="Save" name="Save" /> <br />
<input type=submit value="Delete" name="Delete"/>
</form>

因此,当单击提交按钮时,它首先命中“ActionNameSelector”属性,然后根据触发的提交调用适当的操作。

因此,第一步是创建一个继承自“ActionNameSelectorAttribute”类的类。在这个类中,我们创建了一个简单的属性“Name”。

我们还需要重写返回true或flase的“IsValidName”函数。无论是否执行某个操作,我们都要在这个函数中编写逻辑。因此,如果这个函数返回true,则执行动作,否则不执行。

public class SubmitButtonSelector : ActionNameSelectorAttribute
    {
        public string Name { get; set; }
        public override bool IsValidName(ControllerContext controllerContext, string actionName, System.Reflection.MethodInfo methodInfo)
        {
            // Try to find out if the name exists in the data sent from form
var value = controllerContext.Controller.ValueProvider.GetValue(Name);
            if (value != null)
            {
                return true;
            }
            return false;

        }
    }

上述函数的核心在下面的代码中。“ValueProvider”集合包含从表单中发布的所有数据。因此,它首先查找“Name”值,如果在HTTP请求中找到它,则返回true,否则返回false。

var value = controllerContext.Controller.ValueProvider.GetValue(Name);
if (value != null)
      {
        return true;
      }
      return false;

然后可以在各自的操作上装饰这个属性类,并提供各自的“Name”值。因此,如果提交正在命中这个动作,如果名称与HTML提交按钮名称匹配,则进一步执行该动作,否则不执行。

public class CustomerController : Controller
{
        [SubmitButtonSelector(Name="Save")]
        public ActionResult Save()
        {
            return Content("Save Called");
        }
        [SubmitButtonSelector(Name = "Delete")]
        public ActionResult Delete()
        {
            return Content("Delete Called");
        }
}

我尝试综合所有的解决方案,并创建了一个[ButtenHandler]属性,它可以很容易地处理表单上的多个按钮。

我已经在CodeProject中描述了它在ASP中的多个参数化(本地化)表单按钮。净MVC。

要处理此按钮的简单情况:

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

你会有如下的动作方法:

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

注意按钮的名称与动作方法的名称是如何匹配的。本文还描述了如何让按钮具有值和按钮具有索引。