自定义asp.net mvc 3目录结构

   很多刚开始使用asp.net mvc的朋友,对View的目录结构不太适应,虽然这种目录结构并无不良影响,但层次感确实比较差。对于稍大一些的项目,存在许多Controller,这些controller如果不进行分类组织,都放在一个文件夹下,就是想找到它们也很费劲,当然所对应的view也是一样,好在可以用Area分割组织项目,但使用者很快会发现Area其实就是原有结构的克隆,在主干上通过Areas文件夹,延伸出一个一模一样的东西,显得非常怪异。

        其实大多数人希望象asp.net webform那样,能够自由组织目录结构。对于webform来说,访问某一页面,就是经过一个完整的路径访问所对应的那个物理文件,目录怎么组织都可以,而对于mvc很显然不是这样的,其视图的路径由return View(url)中的url决定。假如你是一个不怕麻烦的人,看到这里就可以了,老老实实的指定这个url如return View("~/Views/X/Y/Z/index.cshtml")就行了,但事实上大多数人都很懒,还是直接return View()或return View(model)来得比较爽,按默认的配置自动查找和匹配相应的view。

        asp.mvc 3有很多扩展点,其中视图引擎(ViewEngine)就是一个,通过对视图引擎的重写能达到自定义view目录结构的目的。下面通过示例来说明具体方法。

 问题:asp.net mvc 3项目中,在原默认结构的基础上,添加了两个Area,一个是Admin,另一个是User,如何组织目录结构?

答曰:

1.controller目录结构随意,毫无影响,甚至可以做为类库放到另一个项目中,如果只想放在一个项目中,建议结构如下:

Controllers
--Admin
        |--Controller1
        |--Controller2
        |--Controller..
--User
        |--Controller1
        |--Controller2
        |--Controller..
--Home(原默认Controller)

在Controllers下新建Admin,User,分别把Areas中的Admin和User中的Controllers移到新建的对应目录中,修改相关类的命名空间(也可不修改)。

然后到对应的AreaRegistration文件中注册控制器命名空间,如在AdminAreaRegistration.cs文件中:

 public override void RegisterArea(AreaRegistrationContext context) {
                 context.MapRoute(
                "Admin_default",
                "Admin/{controller}/{action}/{id}",
                new { controller="Home",action = "Index", id = UrlParameter.Optional },
                null,
                new string[] { "iMONOsHOP.Web.Controllers.Admin" } //注册命名空间
   );
当然可以灵活设置控制器的结构,可以有更深的层次,根据需要只需在new string[]{......}加入多个注册就行了。如果要更改默认主控制器层次结构,还得到Global.asax.cs中注册。

2.View目录结构,按Area--->Controller--->Action组织

Views
--Admin
       |--Controller1
                 |--*.cshtml
       |--Controller2
                  |--*.cshtml
        |--Controller..
--User
       |--Controller1
                 |--*.cshtml
--Home(默认主Controller)
        |--*.cshtml
--Shared
        |--*.cshtml
将areas中Admin,User相关view文件移到对应目录

3.删除Areas目录

4.新建一个CustomerRazorViewEngine.cs文件,代码如下:

public class CustomerRazorViewEngine : RazorViewEngine {

        public CustomerRazorViewEngine(): base() {
            //Area视图路径其中{2},{1},{0}分别代表Area名,Controller名,Action名
            AreaViewLocationFormats = new[] { "~/Views/{2}/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
            //Area模版路径
            AreaMasterLocationFormats = new[] { "~/Views/Shared/{0}.cshtml" };
            //Area的分部视图路径
            AreaPartialViewLocationFormats = new[] { "~/Views/{2}/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
            //主视图路径
            ViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
            //主模版路径
            MasterLocationFormats = new[] { "~/Views/Shared/{0}.cshtml" };
            //主分部视图路径
            PartialViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
        }

        protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) {
            return base.CreatePartialView(controllerContext, partialPath);
        }

        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) {
            return base.CreateView(controllerContext, viewPath, masterPath);
        }

        protected override bool FileExists(ControllerContext controllerContext, string virtualPath) {
            return base.FileExists(controllerContext, virtualPath);
        }
}
5.在Global.asax.cs中注册:
 protected void Application_Start() {
            AreaRegistration.RegisterAllAreas();
            ViewEngines.Engines.Clear();
            //注册自定义视图
            ViewEngines.Engines.Add(new CustomerRazorViewEngine());
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
  }
通过以上步骤就可以实现自定义视图目录结构了,适当修改以上代码可以实现你所需要的任何目录结构。

posted on 2014-01-07 01:20  仗帅闯江湖  阅读(44)  评论(0编辑  收藏  举报

导航