转载地址:http://www.cnblogs.com/wuchang/archive/2010/01/29/1658916.html
有时候会遇到这种情况:在一个表单上需要多个按钮来完成不同的功能,比如一个简单的审批功能。
如果是用webform那不需要讨论,但asp.net mvc中一个表单只能提交到一个Action处理,相对比较麻烦点。
方法一:使用客户端脚本
比如我们在View中这样写:
| 1 2 3 | <inputtype="submit" value="审核通过"  onclick='this.form.action="<%=Url.Action("Action1") %>";' /><inputtype="submit" value="审核不通过"  onclick='this.form.action="<%=Url.Action("Action2") %>";'  /><inputtype="submit" value="返回"   onclick='this.form.action="<%=Url.Action("Action3") %>";' /> | 
在点击提交按钮时,先改变Form的action属性,使表单提交到按钮相应的action处理。
但有的时候,可能Action1和2的逻辑非常类似,也许只是将某个字段的值置为1或者0,那么分开到二个action中又显得有点多余了。
方法二:在Action中判断通过哪个按钮提交
在View中,我们不用任何客户端脚本处理,给每个提交按钮加好name属性:
| 1 2 3 | <inputtype="submit" value="审核通过" name="action" /><inputtype="submit" value="审核不通过"  name="action"/><inputtype="submit" value="返回"  name="action"/> | 
然后在控制器中判断:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [HttpPost]publicActionResult Index(stringaction /* 其它参数*/){    if(action=="审核通过")    {        //    }    elseif(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")]publicActionResult Action1(){    //    returnView();}[HttpPost][MultiButton("action2")]publicActionResult Action2(){    //    returnView();} | 
在 View中:
| 1 2 3 | <inputtype="submit" value="审核通过" name="action1" /><inputtype="submit" value="审核不通过"  name="action2"/><inputtype="submit" value="返回"  name="action3"/> | 
此时,Controller已经无须依赖于按钮的Value值。
MultiButtonAttribute的定义如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | publicclassMultiButtonAttribute : ActionNameSelectorAttribute{    publicstringName { get; set; }    publicMultiButtonAttribute(stringname)    {        this.Name = name;    }    publicoverrideboolIsValidName(ControllerContext controllerContext,        stringactionName, System.Reflection.MethodInfo methodInfo)    {        if(string.IsNullOrEmpty(this.Name))        {            returnfalse;        }        returncontrollerContext.HttpContext.Request.Form.AllKeys.Contains(this.Name);    }} | 
方法四、改进
Thomas Eyde就方法三的方案给出了个改进版:
Controller:
| 1 2 3 4 5 6 7 8 | [HttpPost][MultiButton(Name = "delete", Argument = "id")]publicActionResult Delete(stringid){    varresponse = System.Web.HttpContext.Current.Response;    response.Write("Delete action was invoked with "+ id);    returnView();} | 
View:
| 1 2 | <inputtype="submit" value="not important" name="delete" /><inputtype="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)]publicclassMultiButtonAttribute : ActionNameSelectorAttribute{    publicstringName { get; set; }    publicstringArgument { get; set; }    publicoverrideboolIsValidName(ControllerContext controllerContext, stringactionName, MethodInfo methodInfo)    {        varkey = ButtonKeyFrom(controllerContext);        varkeyIsValid = IsValid(key);        if(keyIsValid)        {            UpdateValueProviderIn(controllerContext, ValueFrom(key));        }        returnkeyIsValid;    }    privatestringButtonKeyFrom(ControllerContext controllerContext)    {        varkeys = controllerContext.HttpContext.Request.Params.AllKeys;        returnkeys.FirstOrDefault(KeyStartsWithButtonName);    }    privatestaticboolIsValid(stringkey)    {        returnkey != null;    }    privatestaticstringValueFrom(stringkey)    {        varparts = key.Split(":".ToCharArray());        returnparts.Length < 2 ? null: parts[1];    }    privatevoidUpdateValueProviderIn(ControllerContext controllerContext, stringvalue)    {        if(string.IsNullOrEmpty(Argument)) return;        controllerContext.Controller.ValueProvider[Argument] = newValueProviderResult(value, value, null);    }    privateboolKeyStartsWithButtonName(stringkey)    {        returnkey.StartsWith(Name, StringComparison.InvariantCultureIgnoreCase);    }} | 
如果是在MVC 2.0中的话,将UpdateValueProviderIn方法改为:
| 1 2 3 4 5 6 | privatevoidUpdateValueProviderIn(ControllerContext controllerContext, stringvalue){    if(string.IsNullOrEmpty(Argument))        return;    controllerContext.RouteData.Values[this.Argument] = value;} | 
 
                    
                     
                    
                 
                    
                 
 
        
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号