是否有一些简单的方法来处理来自同一个表单的多个提交按钮?例如:
<% 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的答案,我提出了一个有点不同的解决方案。我仍然使用ActionNameSelectorAttribute,但我需要处理两个按钮“保存”和“同步”。它们做的几乎是一样的,所以我不想有两个动作。
属性:
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" />
控制器
[MultipleButtonAction("Save", "Sync")]
public ActionResult Sync(OrgSynchronizationEditModel model)
{
var btn = this.RouteData.Values["ButtonName"];
我还想指出,如果动作做不同的事情,我可能会遵循mkozicki的帖子。
其他回答
这是我使用的技巧,但我在这里还没有看到。链接(由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;
}
}
}
给你的提交按钮一个名字,然后在你的控制器方法中检查提交的值:
<% 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());
}
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
如果您的浏览器支持输入按钮的属性格式操作(IE 10+,不确定其他浏览器),那么以下应该工作:
@using (Html.BeginForm()){
//put form inputs here
<input id="sendBtn" value="Send" type="submit" formaction="@Url.Action("Name Of Send Action")" />
<input id="cancelBtn" value="Cancel" type="submit" formaction="@Url.Action("Name of Cancel Action") />
}
您可以像前面提到的那样检查动作中的名称,但是您可能会考虑这是否是好的设计。考虑动作的职责,不要将这种设计过多地与按钮名称等UI方面结合起来,这是一个好主意。所以考虑使用两种形式和两种动作:
<% 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(); %>
此外,在“取消”的情况下,您通常只是不处理表单,而是转到一个新的URL。在这种情况下,你根本不需要提交表单,只需要一个链接:
<%=Html.ActionLink("Cancel", "List", "MyController") %>