根据单击的提交按钮将表单发布到不同的 MVC 发布操作

Posted

技术标签:

【中文标题】根据单击的提交按钮将表单发布到不同的 MVC 发布操作【英文标题】:Posting form to different MVC post action depending on the clicked submit button 【发布时间】:2014-02-02 17:11:43 【问题描述】:

我正在使用ASP.Net MVC 4。我在一个视图上有多个按钮。目前我正在调用相同的操作方法;我正在使用 name 属性区分单击的按钮。

@using (html.BeginForm("Submit", "SearchDisplay", new  id = Model == null ? Guid.NewGuid().ToString() : Model.SavedSearch , FormMethod.Post))

    <div class="leftSideDiv">
        <input type="submit" id="btnExport" class="exporttoexcelButton" 
        name="Command" value="Export to Excel" />
    </div>

    <div class="pageWrapperForSearchSubmit">
        <input type="submit" class="submitButton" 
         value="Submit" id="btnSubmitChange" />
    </div>

//动作

    [HttpPost]
    public ActionResult Submit(SearchCostPage searchModel, string Command)
    
        SessionHelper.ProjectCase = searchModel.ProjectCaseNumber;

        if (string.Equals(Command, Constants.SearchPage.ExportToExcel))
        

        
   

问题

    有没有办法在不同的按钮点击时指向不同的 POST 操作方法(无需自定义路由)? 如果没有自定义路由就没有办法,那么自定义路由怎么办?

参考资料:

    Jimmy Bogard - Cleaning up POSTs in ASP.NET MVC

【问题讨论】:

JS 将允许您预处理您的提交请求,这并不意味着您仍然不能有完整的回发。 我已经发布了答案。 我已编辑您的问题标题以使其更准确,并添加了一个简单有效的答案(在我的一些项目中进行生产)。 为什么不使用多个提交按钮路由 ***.com/questions/442704/… This Tutorial 可能会有所帮助。 【参考方案1】:

您可以根据浏览器的支持以不同的方式选择必须发布表单的 URL(以及调用的操作):

对于支持 HTML5 的较新浏览器,您可以使用formaction attribute of a submit button 对于不支持此功能的旧浏览器,您需要使用一些 javascript 来更改 form's action attribute,单击按钮时和提交之前

这样你就不需要在服务器端做任何特别的事情了。

当然,您可以在 Razor 中使用 Url 扩展方法来指定表单操作。

对于支持 HMTL5 的浏览器:只需像这样定义提交按钮:

<input type='submit' value='...' formaction='@Url.Action(...)' />

对于旧版浏览器,我建议使用这样的不显眼的脚本(将其包含在您的“主布局”中):

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

注意:此脚本将处理页面中具有type=submitdata-form-action 属性的任何元素的点击。发生这种情况时,它会获取data-form-action 属性的值并将包含表单的操作设置为此属性的值。由于它是一个委托事件,它甚至可以用于使用 AJAX 加载的 HTML,而无需采取额外的步骤。

然后您只需将带有所需操作 URL 的 data-form-action 属性添加到您的按钮,如下所示:

<input type='submit' data-form-action='@Url.Action(...)' value='...'/>

请注意,单击按钮会更改表单的操作,然后,浏览器会立即将表单发布到所需的操作。

如您所见,这不需要自定义路由,您可以使用标准的Url 扩展方法,并且在现代浏览器中没有什么特别的事情要做。

【讨论】:

恐怕我做不到。这是我自己做的。请尝试一下,如果您有任何疑问,请写评论,我会通过改进我的答案来帮助您。虽然我认为套件很清楚,你很快就会让它工作。 你能同时使用这两种方法来支持多个浏览器吗?还是必须选择其中之一? JavaScript 解决方案支持新旧浏览器,前提是 JavaScript 未被禁用。同时使用这两种技术(这是可能的)也将涵盖禁用 JavaScript 的 HTML5 兼容浏览器的情况。【参考方案2】:

最佳答案 1:

ActionNameSelectorAttribute 中提到

    How do you handle multiple submit buttons in ASP.NET MVC Framework?

    ASP.Net MVC 4 Form with 2 submit buttons/actions

http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx

答案 2

参考:dotnet-tricks - Handling multiple submit buttons on the same form - MVC Razor

第二种方法

添加一个新的表单来处理取消按钮的点击。现在,点击取消按钮,我们将发布第二个表单并重定向到主页。

第三种方法:客户端脚本

<button name="ClientCancel" type="button" 
    onclick=" document.location.href = $('#cancelUrl').attr('href');">Cancel (Client Side)
</button>
<a id="cancelUrl" href="@Html.AttributeEncode(Url.Action("Index", "Home"))" 
style="display:none;"></a>

【讨论】:

【参考方案3】:

这对我来说听起来就像你拥有的是一个带有 2 个输出的命令,我会选择为此在 客户端和服务器中进行更改。

在客户端,使用 JS 构建您要发布到的 URL(为简单起见使用 JQuery),即

<script type="text/javascript">
    $(function() 
        // this code detects a button click and sets an `option` attribute
        // in the form to be the `name` attribute of whichever button was clicked
        $('form input[type=submit]').click(function() 
            var $form = $('form');
            form.removeAttr('option');
            form.attr('option', $(this).attr('name'));
        );
        // this code updates the URL before the form is submitted
        $("form").submit(function(e)  
            var option = $(this).attr("option");
            if (option) 
                e.preventDefault();
                var currentUrl = $(this).attr("action");
                $(this).attr('action', currentUrl + "/" + option).submit();     
            
        );
    );
</script>
...
<input type="submit" ... />
<input type="submit" name="excel" ... />

现在在服务器端我们可以添加一个新的路由来处理 excel 请求

routes.MapRoute(
    name: "ExcelExport",
    url: "SearchDisplay/Submit/excel",
    defaults: new
    
        controller = "SearchDisplay",
        action = "SubmitExcel",
    );

您可以设置 2 个不同的操作

public ActionResult SubmitExcel(SearchCostPage model)

   ...


public ActionResult Submit(SearchCostPage model)

   ...

或者您可以使用ActionName 属性作为别名

public ActionResult Submit(SearchCostPage model)

   ...


[ActionName("SubmitExcel")]
public ActionResult Submit(SearchCostPage model)

   ...

【讨论】:

【参考方案4】:

您可以使用 ajax 调用来调用不同的方法而无需回发

$.ajax(
    type: "POST",
     url: "@(Url.Action("Action", "Controller"))",
     data: id: 'id', id1: 'id1' ,
     contentType: "application/json; charset=utf-8",
     cache: false,
     async: true,
     success: function (result) 
        //do something
     
);

【讨论】:

我需要一个完整的回发

以上是关于根据单击的提交按钮将表单发布到不同的 MVC 发布操作的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.net MVC 5 应用程序中单击按钮时使用 JavaScript/jQuery 将用户重定向到页面

Spring MVC - 多个提交按钮到表单

如何根据单击的提交按钮选择父表单?

在 asp .NET MVC 中提交表单之前动态地将项目添加到列表中

Javascript:单击提交按钮时如何将隐藏的输入标签附加到表单中?

有没有办法用 1 个提交按钮 mvc 提交 3 个表单