您的位置:首页 > 其它

使用ControllerActionInvoker简化MVC单Form多按钮的提交

2012-08-07 18:24 260 查看
最近在学习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,有不当之处还请指教!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: