是否有一些简单的方法来处理来自同一个表单的多个提交按钮?例如:
<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" value="Send" />
<input type="submit" value="Cancel" />
<% Html.EndForm(); %>
知道如何在ASP中做到这一点吗?NET框架测试版?我在谷歌上搜索的所有例子中都有单个按钮。
是否有一些简单的方法来处理来自同一个表单的多个提交按钮?例如:
<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" value="Send" />
<input type="submit" value="Cancel" />
<% Html.EndForm(); %>
知道如何在ASP中做到这一点吗?NET框架测试版?我在谷歌上搜索的所有例子中都有单个按钮。
当前回答
我来派对已经很晚了,但现在开始… 我的实现借用了@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;
}
}
其他回答
你应该能够为按钮命名并赋予它们一个值;然后将此名称映射为操作的参数。或者,使用2个单独的动作链接或2个表单。
你可以这样写:
<% 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"…
我也遇到过这个“问题”,但通过添加name属性找到了一个相当合理的解决方案。我不记得在其他语言中有这个问题。
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2
... 如果表单包含多个提交按钮,则只有激活的提交按钮是成功的。 ...
这意味着以下代码值属性可以被更改、本地化、国际化,而不需要额外的代码检查强类型资源文件或常量。
<% 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(); %>`
在接收端,您只需要检查是否有任何已知的提交类型不是空
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
}
}
David Findley在他的ASP上写了3种不同的选择。网络博客。
阅读文章的多个按钮以相同的形式查看他的解决方案,以及每个方案的优缺点。恕我直言,他提供了一个非常优雅的解决方案,利用属性,你装饰你的行动。
这是我使用的技巧,但我在这里还没有看到。链接(由Saajid Ismail发布 )启发这个解决方案的是http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form.aspx)。它适应Dylan Beattie的答案做本地化没有任何问题。
在视图中:
<% 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;
}
}
}