为 ASP.NET MVC 项目添加“模块”(module)

25 篇文章 0 订阅
17 篇文章 1 订阅

先说说何为“模块”,如果你用过 php 的 zend framework 框架就理解这个概念和使用的必要性。举个例子来说,有一个项目,这个项目有前台(给用户访问的模块)和后台(给管理员访问的模块),而前台和后台中又有不同的子模块(页面)。这里仅仅使用 controller 和 action 就显的有点为难了,原因在于,前台和后台中极有可能出现相同名称的 controller,对于这种情况 zf 框架处理的要好些,它引入的 module 的概念。

针对刚才说的例子来讲,就是把前台当做一个 module ,后台当做一个 module。不同的 module 中拥有各自的 controller、view,而不同的 module 中的controller 和 view 可以使用相同的名字,当然,对于 controller 来说就不能在同一个命名空间了。

现在,我要做的就是在 ASP.NET MVC 中实现 zf 的这种机制。


注:ASP.NET MVC 2.0 中已引入 Area 概念,用于实现类似的功能。


一、从路由开始改造

先看我的两个模块的路由配置(后台管理模块:Admin、用户模块:User):

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                "Admin",
                "Admin/{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                new string[] { "Controllers.Admin" }
            );
            routes.MapRoute(
                "User",
                "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                new string[] { "Controllers.User" }
            );
        }


这里创建二个路由配置:

路径如“Admin/Login/Index”的访问使用第一个配置,即:Controllers.Admin 命名空间中 Login 类的 Index 方法。

路径如“Home/Index”的访问使用第二个配置,即:Controllers.User 命名空间中 Home 类的 Index 方法。

我是这样设置我的项目目录的:

在原有的Controller下创建Admin、User两个文件夹,其中的类所在的命名空间就分别为:Controllers.Admin、Controllers.User


二、继承  WebFormViewEngine

使用 Reflector 查看  C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 2\Assemblies\System.Web.Mvc.dll 中 System.Web.Mvc.WebFormViewEngine 类的构造函数是这样的:

public WebFormViewEngine()
{
    base.MasterLocationFormats = new string[] { "~/Views/{1}/{0}.master", "~/Views/Shared/{0}.master" };
    base.AreaMasterLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.master", "~/Areas/{2}/Views/Shared/{0}.master" };
    base.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.aspx", "~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.aspx", "~/Views/Shared/{0}.ascx" };
    base.AreaViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.aspx", "~/Areas/{2}/Views/{1}/{0}.ascx", "~/Areas/{2}/Views/Shared/{0}.aspx", "~/Areas/{2}/Views/Shared/{0}.ascx" };
    base.PartialViewLocationFormats = base.ViewLocationFormats;
    base.AreaPartialViewLocationFormats = base.AreaViewLocationFormats;
}

 

这里就是 mvc 搜索视图的地方,那么我们来继承这个类,并改写搜索的路径:

    public class CustomViewEngine : WebFormViewEngine
    {
        public CustomViewEngine(string module)
        {
            base.MasterLocationFormats = new string[] {
                "~/Views/" + module + "/{1}/{0}.master",
                "~/Views/" + module + "/Shared/{0}.master",
                "~/Views/Shared/{0}.master"
            };
            base.ViewLocationFormats = new string[] { 
                "~/Views/" + module + "/{1}/{0}.aspx",
                "~/Views/" + module + "/{1}/{0}.ascx",
                "~/Views/" + module + "/Shared/{0}.aspx",
                "~/Views/" + module + "/Shared/{0}.ascx",
                "~/Views/Shared/{0}.aspx",
                "~/Views/Shared/{0}.ascx"
            };
            base.PartialViewLocationFormats = base.ViewLocationFormats;
            base.AreaPartialViewLocationFormats = base.AreaViewLocationFormats;
        }
    }

这里我多加了一个参数,这个参数就是 module 的名称。这里假设 module 为“Admin”,则改写后的功能是这样的:

1、先在 Views/Admin/Controller 中找 action,找不到转第2步

2、在 Views/Admin/Controller/Shared 中找 action,找不到转第3步

3、在 Views/Shared 中找,如果还找不到会报错

这里,不论是 master、aspx、ascx 都是这样找的。


三、创建一个控制器基类

如下类:

    public class CustomController: Controller 
    {
        private static CustomViewEngine customViewEngine;

        public CustomController(string module)
        {
            customViewEngine = new CustomViewEngine(module);
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new WebFormViewEngine());
            ViewEngines.Engines.Add(customViewEngine);
        }
    } 

这样我就定义了一个自己的控制器,对于以后 MVC 中创建的控制器都要继承至这个控制器。

功能就不多说了,module 就是模块的名称,任何要继承这个控制器的类都要给这个参数。


四、创建 Controller

现在开始可以使用以上代码了,先在 Controller/Admin 下创建一个控制器:

    [HandleError]
    public class LoginController : CustomController
    {
        public ActionResult Index()
        {
            ViewData["Message"] = " Admin 模块";

            return View();
        }
        public LoginController()
            : base("Admin")
        { }
    }

很简单是不?


五、再来创建 View

在 Views/Admin/Login 下创建一个 Index.aspx 视图文件:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Admin/Login
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>管理员模块:<%= Html.Encode(ViewData["Message"]) %></h2>
</asp:Content>


类似的你可以创建 User 模块中的 Controller、View 

现在就可以用 /Admin/Login/Index 看到效果了吧?











  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值