带有多个不同提交按钮的MVC Razor表单?

71

一个 Razor 视图内有 3 个按钮在一个表单内。每个按钮的操作都需要表单值,这些值基本上是来自输入字段的值。

每当我点击任何一个按钮时,它都会将我重定向到默认操作。您能否指导我如何根据按钮按下提交表单到不同的操作?

非常感谢您的时间、指导和帮助。


请展示一些代码...你尝试过什么?也许,从问题中可以看出jquery对你有帮助。 - now he who must not be named.
你所要求的直接做不到,但可以通过变通方法实现,请查看此链接:https://dev59.com/uXfZa4cB1Zd3GeqPV8c2#19272670 - AthibaN
请展示您的代码片段。 - Lamloumi Afif
可能是ASP.NET MVC框架中如何处理多个提交按钮?的重复问题。 - KyleMit
这种问题以前已经被问过了,我的一个答案在这里在MVC中使用多个提交按钮。希望能有所帮助。 - Jeff D
14个回答

104

你也可以尝试这个:

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

这会让提交按钮显示标签为“submit1”之类的吗? - BerggreenDK
2
问题不在于标签。但是,在这个例子中,按钮会被标记为submit1和submit2。 - Jeroen Doppenberg
2
@BerggreenDK:如果你需要不同的标签,可以使用<button>而不是<input>。 - Pavel V.
这段代码并不能完全运行。你需要改为以下方式: string buttonvalue = Request.Form["submitbutton1"]; if(buttonvalue != null) { ... - pianocomposer

93

这个优雅的解决方案适用于多个提交按钮:

@Html.Begin()
{
  // Html code here
  <input type="submit" name="command" value="submit1" />
  <input type="submit" name="command" value="submit2" />

}

在你的控制器动作方法中将其作为参数接受。

public ActionResult Create(Employee model, string command)
{
    if(command.Equals("submit1"))
    {
      // Call action here...
    }
    else
    {
      // Call another action here...
    }
}

5
太棒了!希望我能够给你更多的赞! - SNag
@PaulZahra:这是我使用的一个解决方案。我不需要削减你的解决方案才能再次发布或转发它。请立即取消投票。 - Priyank Sheth
1
@SimpleMan 我并不是在声称对某个解决方案拥有版权... 我的意思并不是暗示你进行了复制粘贴... 我想表达的是,你的回答实际上是我14分钟前发布的答案的重复... 因此我给它投了反对票... 这不公平吗? - Paul Zahra
@PaulZahra 我不认为这是重复的。很多人在几分钟或几小时内发布相同的答案。那么这是否意味着他们应该被踩?你认为这对任何人都有好处吗?你逐行比较了我们的答案吗?你在哪里发现了重复?请合理地证明它。 - Priyank Sheth
@JeremyThompson 谢谢,已解决。 - Paul Zahra
显示剩余3条评论

18

在这个观点中

<form action="/Controller_name/action" method="Post>

 <input type="submit" name="btn1" value="Ok" />
 <input type="submit" name="btn1" value="cancel" />
 <input type="submit" name="btn1" value="Save" />
</form>

在行动中

string str =Request.Params["btn1"];
if(str=="ok"){


}
if(str=="cancel"){


}
if(str=="save"){


}

10

您可以使用JS + Ajax。例如,如果您有任何按钮,您可以在点击事件上告诉它该执行什么操作。以下是代码:

 <input id="btnFilterData" type="button" value="myBtn">

在HTML中,你可以使用以下代码创建一个按钮:

<button>按钮</button>

在脚本部分,你需要使用以下代码(该部分应放在文档末尾):

<script>
// 在这里写你的JavaScript代码
</script>
<script type="text/javascript">
$('#btnFilterData').click(function () {
    myFunc();
});
</script>

最后,您需要添加ajax函数(在另一个脚本部分中,应放置在文档的开头):

并最后,你需要添加ajax功能(在另一个脚本段中,应该放在文档的开头位置):

function myFunc() {
    $.ajax({
        type: "GET",
        contentType: "application/json",
        url: "/myController/myFuncOnController",
        data: {
             //params, which you can pass to yu func
        },
        success: function(result) {

        error: function (errorData) {

        }
    });
};

另一个很好的答案,保持角色分离。没有人应该需要触及控制器来进行此类UI更改。 - Charles Roberto Canato

5
这是对我有效的方法。
formaction="@Url.Action("Edit")"

片段:

 <input type="submit" formaction="@Url.Action("Edit")" formmethod="post" value="Save" class="btn btn-primary" />

<input type="submit" formaction="@Url.Action("PartialEdit")" formmethod="post" value="Select Type" class="btn btn-primary" />

 [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit( Quote quote)
        {
           //code 
       }
 [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult PartialEdit(Quote quote)
        {
           //code
        }

对于想要使用选择器或客户端脚本而不是一个方法来拥有两个不同操作方法的人可能会有所帮助。


1
你如何在没有MVC的情况下在Razor Pages中使用它?formaction一直将我带到默认的表单操作“Course”。当我想要去“Courses_Temp”时怎么办? - JustJohn

4
我找到的最简洁的解决方案如下:
这个例子是为了执行两个非常不同的操作;基本原则是使用"value"来将数据传递给动作。
在你的视图中:
@using (Html.BeginForm("DliAction", "Dli", FormMethod.Post, new { id = "mainForm" }))
{
    if (isOnDli)
    {
        <button name="removeDli" value="@result.WeNo">Remove From DLI</button>
    }
    else
    {
        <button name="performDli" value="@result.WeNo">Perform DLI</button>
    }
}

然后在你的动作中:

    public ActionResult DliAction(string removeDli, string performDli)
    {
        if (string.IsNullOrEmpty(performDli))
        {
            ...
        }
        else if (string.IsNullOrEmpty(removeDli))
        {
            ...
        }

        return View();
    }

这段代码应该很容易改动以实现不同的变化,例如将按钮名称更改为相同,则只需要在操作中使用一个参数,可以看到如下:

在您的视图中:

@using (Html.BeginForm("DliAction", "Dli", FormMethod.Post, new { id = "mainForm" }))
{

        <button name="weNo" value="@result.WeNo">Process This WeNo</button>

        <button name="weNo" value="@result.WeNo">Process A Different WeNo This Item</button>
}

然后在你的操作中:

    public ActionResult DliAction(string weNo)
    {
        // Process the weNo...

        return View();
    }

4
尝试在您的视图中,将每个按钮都包装在其自己的表单中。
  @using (Html.BeginForm("Action1", "Controller"))
  {
    <input type="submit" value="Button 1" />
  }

  @using (Html.BeginForm("Action2", "Controller"))
  {
    <input type="submit" value="Button 2" />
  }

3
如果我需要两个按钮的表单数值,但是我希望根据不同的操作(比如编辑或删除)采取不同的行动呢? - Chad

3
您可以使用普通按钮(非提交按钮)。使用 JavaScript 在“onclick”事件中重写表单的“action”属性为您想要的内容,然后提交表单。使用自定义辅助程序(在项目根目录下的 App_Code 文件夹中创建一个名为“Helper.cshtml”的文件)生成按钮。
@helper SubmitButton(string text, string controller,string action)
{   
    var uh = new System.Web.Mvc.UrlHelper(Context.Request.RequestContext);
    string url = @uh.Action(action, controller, null);   
    <input type=button  onclick="(
                                       function(e)
                                                 {
                                                   $(e).parent().attr('action', '@url'); //rewrite action url
                                                   //create a submit button to be clicked and removed, so that onsubmit is triggered
                                                   var form = document.getElementById($(e).parent().attr('id'));
                                                   var button = form.ownerDocument.createElement('input');
                                                   button.style.display = 'none';
                                                   button.type = 'submit';
                                                   form.appendChild(button).click(); 
                                                   form.removeChild(button);              
                                                  }
                                      )(this)" value="@text"/>
}

然后将其用作:

@Helpers.SubmitButton("Text for 1st button","ControllerForButton1","ActionForButton1")
@Helpers.SubmitButton("Text for 2nd button","ControllerForButton2","ActionForButton2")
...

在您的表单内部。


1
虽然被选中的答案和其他大部分答案都是可行的,但我更愿意选择这个答案,因为它很好地保持了角色的分离。控制器不应该被修改以适应此类UI更改(前提是您已经准备好了控制器逻辑)。因此,使用JavaScript将更改保留在其所属的位置:仅限于UI。 - Charles Roberto Canato

3

最简单的方法是使用html5 FormActionFormMethod

<input type="submit" 
           formaction="Save"
           formmethod="post" 
           value="Save" />
    <input type="submit"
           formaction="SaveForLatter"
           formmethod="post" 
           value="Save For Latter" />
    <input type="submit"
           formaction="SaveAndPublish"
           formmethod="post"
           value="Save And Publish" />

[HttpPost]
public ActionResult Save(CustomerViewModel model) {...}

[HttpPost]
public ActionResult SaveForLatter(CustomerViewModel model){...}

[HttpPost]
public ActionResult SaveAndPublish(CustomerViewModel model){...}

我们可以采用许多其他方法,参见此文章:ASP.Net MVC 多按钮提交在不同情况下的用法


2

除了 @Pablo 的答案之外,对于较新版本,您还可以使用 asp-page-handler 标签助手。

在页面中:

<button asp-page-handler="Action1" type="submit">Action 1</button>
<button asp-page-handler="Action2" type="submit">Action 2</button>

然后在控制器中:

    public async Task OnPostAction1Async() {...}
    public async Task OnPostAction2Async() {...}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接