zoukankan      html  css  js  c++  java
  • ASP.NET MVC中实现多个按钮提交的几种方法【转】

    本文转自:http://www.cnblogs.com/wuchang/archive/2010/01/29/1658916.html


    有时候会遇到这种情况:在一个表单上需要多个按钮来完成不同的功能,比如一个简单的审批功能。

     image

    如果是用webform那不需要讨论,但asp.net mvc中一个表单只能提交到一个Action处理,相对比较麻烦点。

    方法一:使用客户端脚本

    比如我们在View中这样写:

    1
    2
    3
    <input type="submit" value="审核通过"  onclick='this.form.action="<%=Url.Action("Action1") %>";' />
    <input type="submit" value="审核不通过"  onclick='this.form.action="<%=Url.Action("Action2") %>";'  />
    <input type="submit" value="返回"   onclick='this.form.action="<%=Url.Action("Action3") %>";' />

    在点击提交按钮时,先改变Form的action属性,使表单提交到按钮相应的action处理。

    但有的时候,可能Action1和2的逻辑非常类似,也许只是将某个字段的值置为1或者0,那么分开到二个action中又显得有点多余了。

    方法二:在Action中判断通过哪个按钮提交

    在View中,我们不用任何客户端脚本处理,给每个提交按钮加好name属性:

    1
    2
    3
    <input type="submit" value="审核通过" name="action" />
    <input type="submit" value="审核不通过"  name="action"/>
    <input type="submit" value="返回"  name="action"/>

    然后在控制器中判断:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    [HttpPost]
    public ActionResult Index(string action /* 其它参数*/)
    {
        if (action=="审核通过")
        {
            //
        }
        else if (action=="审核不通过")
        {
            //
        }
        else
        {
            //
        }
    }

    几年前写asp代码的时候经常用这样的方法…

    View变得简单的,Controller复杂了。

    太依赖说View,会存在一些问题。假若哪天客户说按钮上的文字改为“通过审核”,或者是做个多语言版的,那就麻烦了。

    参考:http://www.ervinter.com/2009/09/25/asp-net-mvc-how-to-have-multiple-submit-button-in-form/

    方法三:使用ActionSelector

    关于ActionSelector的基本原理可以先看下这个POST使用ActionSelector控制Action的选择

    使用此方法,我们可以将控制器写成这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [HttpPost]
    [MultiButton("action1")]
    public ActionResult Action1()
    {
        //
        return View();
    }
    [HttpPost]
    [MultiButton("action2")]
    public ActionResult Action2()
    {
        //
        return View();
    }

    在 View中:

    1
    2
    3
    <input type="submit" value="审核通过" name="action1" />
    <input type="submit" value="审核不通过"  name="action2"/>
    <input type="submit" value="返回"  name="action3"/>

    此时,Controller已经无须依赖于按钮的Value值。

    MultiButtonAttribute的定义如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class MultiButtonAttribute : ActionNameSelectorAttribute
    {
        public string Name { get; set; }
        public MultiButtonAttribute(string name)
        {
            this.Name = name;
        }
        public override bool IsValidName(ControllerContext controllerContext,
            string actionName, System.Reflection.MethodInfo methodInfo)
        {
            if (string.IsNullOrEmpty(this.Name))
            {
                return false;
            }
            return controllerContext.HttpContext.Request.Form.AllKeys.Contains(this.Name);
        }
    }

    参考:http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx

    方法四、改进

    Thomas Eyde就方法三的方案给出了个改进版:

    Controller:

    1
    2
    3
    4
    5
    6
    7
    8
    [HttpPost]
    [MultiButton(Name = "delete", Argument = "id")]
    public ActionResult Delete(string id)
    {
        var response = System.Web.HttpContext.Current.Response;
        response.Write("Delete action was invoked with " + id);
        return View();
    }

    View:

    1
    2
    <input type="submit" value="not important" name="delete" />
    <input type="submit" value="not important" name="delete:id" />

    MultiButtonAttribute定义:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class MultiButtonAttribute : ActionNameSelectorAttribute
    {
        public string Name { get; set; }
        public string Argument { get; set; }
     
        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
        {
            var key = ButtonKeyFrom(controllerContext);
            var keyIsValid = IsValid(key);
     
            if (keyIsValid)
            {
                UpdateValueProviderIn(controllerContext, ValueFrom(key));
            }
     
            return keyIsValid;
        }
     
        private string ButtonKeyFrom(ControllerContext controllerContext)
        {
            var keys = controllerContext.HttpContext.Request.Params.AllKeys;
            return keys.FirstOrDefault(KeyStartsWithButtonName);
        }
     
        private static bool IsValid(string key)
        {
            return key != null;
        }
     
        private static string ValueFrom(string key)
        {
            var parts = key.Split(":".ToCharArray());
            return parts.Length < 2 ? null : parts[1];
        }
     
        private void UpdateValueProviderIn(ControllerContext controllerContext, string value)
        {
            if (string.IsNullOrEmpty(Argument)) return;
            controllerContext.Controller.ValueProvider[Argument] = new ValueProviderResult(value, value, null);
        }
     
        private bool KeyStartsWithButtonName(string key)
        {
            return key.StartsWith(Name, StringComparison.InvariantCultureIgnoreCase);
        }
    }

    如果是在MVC 2.0中的话,将UpdateValueProviderIn方法改为:

    1
    2
    3
    4
    5
    6
    private void UpdateValueProviderIn(ControllerContext controllerContext, string value)
    {
        if (string.IsNullOrEmpty(Argument))
            return;
        controllerContext.RouteData.Values[this.Argument] = value;
    }
  • 相关阅读:
    Luogu 1080 【NOIP2012】国王游戏 (贪心,高精度)
    Luogu 1314 【NOIP2011】聪明的质检员 (二分)
    Luogu 1315 【NOIP2011】观光公交 (贪心)
    Luogu 1312 【NOIP2011】玛雅游戏 (搜索)
    Luogu 1525 【NOIP2010】关押罪犯 (贪心,并查集)
    Luogu 1514 引水入城 (搜索,动态规划)
    UVA 1394 And Then There Was One / Gym 101415A And Then There Was One / UVAlive 3882 And Then There Was One / POJ 3517 And Then There Was One / Aizu 1275 And Then There Was One (动态规划,思维题)
    Luogu 1437 [HNOI2004]敲砖块 (动态规划)
    Luogu 1941 【NOIP2014】飞扬的小鸟 (动态规划)
    HDU 1176 免费馅饼 (动态规划)
  • 原文地址:https://www.cnblogs.com/booth/p/2549009.html
Copyright © 2011-2022 走看看