最近在学习MVC,碰到了一个表单多个提交按钮的处理问题,网上找了一些方法,总觉的不够方便,下面说说我的解决方案:
一、View中我们有如下表单
@using (Ajax.BeginForm(new AjaxOptions()))
{
<input type="submit" name="Submit:Save" value="保存" class="Button" />
<input type="submit" name="Submit:Confirm" value="确认" class="Button" />
<input type="submit" name="Submit:Audit" value="审核" class="Button" />
}
个人比较喜欢无刷新,所以用Ajax.BeginForm,当然你也可以用Html.BeginForm。
我们假设该表单对应的Url为:http://localhost/MvcApp/BusinessCost,由于没有默认的Action,所以实际该请求会路由到BusinessCostController的Index方法。
提交按钮的名称我们以“Submit:”开头,后面跟要执行Action的名称。这样可以很简单的控制这个提交按钮执行哪个Action。
二、BusinessCostController中的方法
public class PermissionRegistrationController : Test.Web.Mvc.Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Save(...)
{
return View();
}
public ActionResult Confirm(...)
{
return View();
}
public ActionResult Audit(...)
{
return View();
}
}
上面方法的参数我没有写,这个不影响我们要操作的内容。
上面我们注意到并没有继承System.Web.Mvc.Controller,而是继承我自己的Test.Web.Mvc.Controller,这样的好处是我们可以放很多通用的东西到自己的Controller中,也是实现本功能的关键点之一。
三、自定义的Test.Web.Mvc.Controller基类
public class Controller : System.Web.Mvc.Controller
{
public Controller()
: base()
{
}
protected override IActionInvoker CreateActionInvoker()
{
return new MultiSubmitControllerActionInvoker();
}
}
在这个基类中我们重写CreateActionInvoker方法,返回我们自己定义的MultiSubmitControllerActionInvoker类。
当然,这个基类也可以增加其他的通用方法,或者重写其他父类中的方法从而实现更复杂的逻辑控制。
四、主角上场-最重要的MultiSubmitControllerActionInvoker类
public class MultiSubmitControllerActionInvoker : ControllerActionInvoker
{
public override bool InvokeAction(ControllerContext controllerContext, string actionName)
{
if (controllerContext.HttpContext.Request.HttpMethod.Equals("POST"))//我这里只有POST才执行特殊逻辑,其实也可以GET
{
string virtualPath = controllerContext.RouteData.Route.GetVirtualPath(controllerContext.RequestContext, controllerContext.RouteData.Values).VirtualPath;
if (!virtualPath.EndsWith("/" + actionName))//只有当Url中没有Action的时候才执行特殊逻辑,如果本身已经有了就执行系统确定的吧!
{
string actionButtonName = controllerContext.HttpContext.Request.Form.AllKeys.FirstOrDefault(key => key.StartsWith("Submit:", StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(actionButtonName))//检查提交按钮的name是否符合我们的约定
{
actionName = actionButtonName.Substring(actionButtonName.IndexOf(":") + 1);//符合约定取出冒号后面的名字作为Action的名字
}
}
}
return base.InvokeAction(controllerContext, actionName);
}
}
在我们自定义的ControllerActionInvoker中重写InvokeAction方法。从而决策改变actionName,达到我们想要的结果。
搞定!只要继承我们自己的基类,就可以实现点击提交按钮,从而根据提交按钮的name来判断执行Controller中的哪个Action了。也不用给Action的方法加Attribute,是不是很简单?
本人初学MVC,有不当之处还请指教!
本文介绍了一种通过自定义Controller基类实现表单多个提交按钮与对应MVC控制器方法的简单映射策略,使得前端表单操作与后端逻辑处理更加清晰、高效。
3571

被折叠的 条评论
为什么被折叠?



