【问题标题】:Multiple submit buttons with different actions and controllers but shared input name/values具有不同操作和控制器但共享输入名称/值的多个提交按钮
【发布时间】:2012-09-17 08:01:14
【问题描述】:

编辑:阅读我的问题的底部,看看我实际做了什么。我接受了不同的答案,但因为我的解决方案需要 AngularJS。


我正在使用 C# 4.0 和 MVC 3/Razor。我更愿意利用框架的现有功能,而不是制作我自己的辅助类。这是我正在做的,简化的:

这是我的模型:

MyModel.cs

public class MyModel
{
    public string Name { get; set; }
    public int ID { get; set; }
}

到目前为止,我的看法:

Index.cshtml

@model IEnumerable<MyModel>

Please select a Model.

<select name="id">
    @foreach (var m in Model)
    {
        <option value="@(m.ID)">@(m.ID) - @(m.Name)</option>
    }
</select>

还有我的控制器:

MyController.cs

public class MyController : Controller
{
    public ActionResult Index() { /* ... */ }
    public ActionResult Display(int id) { /* ... */ }
    public ActionResult Delete(int id) { /* ... */ }
    public ActionResult Edit(int id) { /* ... */ }
}

在我看来,我想要三个提交按钮,每个按钮链接到不同的控制器/动作,一个用于编辑、删除和显示。但是,我希望传递用户选择的 ID(通过 GET)。我该怎么做?

我知道我可以创建一个新的控制器动作,其唯一目的是根据 submit 类型 input 元素的 value 来确定选择三个中的哪一个,但这种方法对我来说似乎很难看;我想绕过这一步。理想情况下,我想要这样的东西:

@using (Html.BeginForm("", "", FormMethod.Get))
{
    <select name="id">
        @foreach (var m in Model)
        {
            <option value="@(m.ID)">@(m.ID) - @(m.Name)</option>
        }
    </select>

    @Html.SubmitButton("Edit", "My")
    @Html.SubmitButton("Delete", "My")
    @Html.SubmitButton("Display", "My")
}

但我在 Html 中找不到任何似乎做类似事情的方法签名。


编辑:

这就是我最终的结果。它使用一个名为 AngularJS 的 JavaScript 库,但不需要额外的 JavaScript 管道。它只是工作。

@model IEnumerable<MyModel>
<html>
    <head>
        <script type="text/javascript" src="../../Scripts/angular.js"></script>
    </head>
    <body ng-app>
        <select ng-model="ID">
            @foreach (var m in Model)
            {
                <option value="@(m.ID)">@(m.ID) - @(m.Name)</option>
            }
        </select>

        @{
            var forms = new[] 
            {
                new { ActionName = "Display", ControllerName = "My" },
                new { ActionName = "Edit", ControllerName = "My" },
                new { ActionName = "Delete", ControllerName = "My" }
            };

            foreach (var form in forms)
            {
                using (Html.BeginForm(form.ActionName, form.ControllerName, FormMethod.Get))
                {
                    <input type="submit" value="@(form.ActionName)" ng-disabled="ID == null"/>
                    <input type="hidden" name="id" value="{{ID}}"/>
                }
            }
        }

    </body>
</html>

【问题讨论】:

    标签: c# asp.net-mvc c#-4.0 razor angularjs


    【解决方案1】:

    你可以(我已经)使用属性来做到这一点。尝试了几个different variations 的主题后,我选择了这个:

    http://blog.ashmind.com/2010/03/15/multiple-submit-buttons-with-asp-net-mvc-final-solution/

    它基本上根据您提交的名称进行路由。对于您的情况:

     <input type="submit" name="delete" value="Delete" />
     <input type="submit" name="Edit" value="Edit" />
    

    和控制器

    public class MyController : Controller {
        [HttpParamAction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id) {
        }
    
        [HttpParamAction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int id) {
    
        }
    }
    

    属性

      public class HttpParamActionAttribute : ActionNameSelectorAttribute {
            public override bool IsValidName(ControllerContext controllerContext,  
                                           string actionName, MethodInfo methodInfo) 
    
    
     {
    
                if (actionName.Equals(methodInfo.Name,  
                                      StringComparison.InvariantCultureIgnoreCase))
                    return true;
    
                if (!actionName.Equals("Action", 
                                       StringComparison.InvariantCultureIgnoreCase))
                    return false;
    
                var request = controllerContext.RequestContext.HttpContext.Request;
                return request[methodInfo.Name] != null;
            }
        }
    

    【讨论】:

      【解决方案2】:

      对于EditDisplay,显然,您不需要提交表单。您可以为此使用 GET。因此 Html.ActionLink 辅助方法可用于显示一个链接,该链接将用户带到适当的屏幕(操作方法)。

      要从链接中的下拉列表中传递所选项目的值,您可以在单击事件上使用 java 脚本获取所选值并将其发送到操作方法。

      @Html.ActionLink("Edit","Edit","YourController",null ,new {@class="lnk"})
      @Html.ActionLink("Display","Display","YourController",null ,new {@class="lnk"})
      @Html.ActionLink("Delete","Delete","YourController",null ,new {@class="lnk"})
      

      现在javascript来捕捉这些链接的点击事件

      $(function(){
        $("a.lnk").click(function(e){
           e.preventDefault();
           var targetUrl=$(this).attr("href");
           var selectedVal=$("#YourDropdownID").val();
           targetUrl=targetUrl+"?id="+selectedVal;
           window.location.href=url;
        });
      });
      

      对于删除,您可以显示一个链接,将用户带到一个确认屏幕,然后您可以有一个提交按钮,该按钮执行 HTTPPOST 提交。

      您可以自定义 CSS 以使 a 标记看起来像一个提交按钮

      另外,不要在视图中使用 foreach 循环呈现下拉列表。在 MVC 中已经有 HTML Helper 方法可以做到这一点。您应该始终使用它。 Here 是一个解释如何做到这一点的答案。

      【讨论】:

      • 这种方法不允许我使用 HTML 选择列表,是吗?
      • 你想在下拉列表中传递所选项目的 ID 吗?
      • 是的。而且我不想使用 JavaScript,因为这看起来应该很简单。
      • 你需要使用javascript来处理。
      • 看来您对 JavaScript 的看法是正确的。然而,通过使用 Angular(直到我询问后我才想到),我能够非常简单直接地做到这一点。没有管道; Angular 刚刚解决了它!
      猜你喜欢
      • 1970-01-01
      • 2011-12-13
      • 2018-11-24
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 2016-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多