asp.net mvc 多级文件夹

版权声明:本文为博主原创文章,未经博主允许不得转载。
ASP.NET MVC出来这么久了,心中却又很多的疑惑:为什么所有的View都要放在Views目录下? 为什么Shared文件夹下面的页面可以被共享? 为什么Page既可以是*.cshtml,也可以是*.aspx?
其实上面的几个问题归结起来都是视图引擎的功效。
在传统的ASP.NET中,可能还没有ViewEngine的概念。因为在Web From里面,实现Page实现了IHttpHanlder的接口,所以Page既是响应的处理类,也是视图的渲染类。在ASP.NET MVC中,视图的概念被抽象了出来,试图引擎的概念也被抽象成了一个接口。
首先来看一下IViewEngine接口的定义:
- namespace System.Web.Mvc
- {
- public interface IViewEngine
- {
- ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
- ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
- void ReleaseView(ControllerContext controllerContext, IView view);
- }
- }
总共3个函数,总结起来大概就是两个功能:Find & Release。
默认情况下,ASP.NET MVC提供了两个视图引擎:WebFormViewEngine和RazorViewEngine。
- namespace System.Web.Mvc
- {
- public static class ViewEngines
- {
- private static readonly ViewEngineCollection _engines = new ViewEngineCollection
- {
- new WebFormViewEngine(),
- new RazorViewEngine(),
- };
- public static ViewEngineCollection Engines
- {
- get { return _engines; }
- }
- }
- }
这就是为什么ASP.NET MVC既支持*.aspx,又支持*.cshtml的原因了(个人觉得如果已经确定要使用RazorView的话,不如把WebFormViewEngine给移除,可能对性能会有所帮助)。
那为什么所有的视图都要放在Views目录下呢,这个就要拜RazorViewngines所赐了。
下面是RazorViewEngine的构造函数:
- public RazorViewEngine(IViewPageActivator viewPageActivator)
- : base(viewPageActivator)
- {
- AreaViewLocationFormats = new[]
- {
- "~/Areas/{2}/Views/{1}/{0}.cshtml",
- "~/Areas/{2}/Views/{1}/{0}.vbhtml",
- "~/Areas/{2}/Views/Shared/{0}.cshtml",
- "~/Areas/{2}/Views/Shared/{0}.vbhtml"
- };
- AreaMasterLocationFormats = new[]
- {
- "~/Areas/{2}/Views/{1}/{0}.cshtml",
- "~/Areas/{2}/Views/{1}/{0}.vbhtml",
- "~/Areas/{2}/Views/Shared/{0}.cshtml",
- "~/Areas/{2}/Views/Shared/{0}.vbhtml"
- };
- AreaPartialViewLocationFormats = new[]
- {
- "~/Areas/{2}/Views/{1}/{0}.cshtml",
- "~/Areas/{2}/Views/{1}/{0}.vbhtml",
- "~/Areas/{2}/Views/Shared/{0}.cshtml",
- "~/Areas/{2}/Views/Shared/{0}.vbhtml"
- };
- ViewLocationFormats = new[]
- {
- "~/Views/{1}/{0}.cshtml",
- "~/Views/{1}/{0}.vbhtml",
- "~/Views/Shared/{0}.cshtml",
- "~/Views/Shared/{0}.vbhtml"
- };
- MasterLocationFormats = new[]
- {
- "~/Views/{1}/{0}.cshtml",
- "~/Views/{1}/{0}.vbhtml",
- "~/Views/Shared/{0}.cshtml",
- "~/Views/Shared/{0}.vbhtml"
- };
- PartialViewLocationFormats = new[]
- {
- "~/Views/{1}/{0}.cshtml",
- "~/Views/{1}/{0}.vbhtml",
- "~/Views/Shared/{0}.cshtml",
- "~/Views/Shared/{0}.vbhtml"
- };
- FileExtensions = new[]
- {
- "cshtml",
- "vbhtml",
- };
- }
所有的寻址路径都被格式化了,是不是很眼熟呢,关于这里为啥用数组而不用List,个人觉得,数组的寻址效率要更高些,遍历速度更快。
好了,找了“罪魁祸首”,就好好地调教一个,让它乖乖听话,小样让去哪就去哪里。
- namespace MvcApplicatin.Web.Mvc.ViewEngine
- {
- public sealed class CustomViewEngine : RazorViewEngine
- {
- public CustomViewEngine()
- {
- ViewLocationFormats = new[]
- {
- "~/Views/{1}/{0}.cshtml",
- "~/Views/Shared/{0}.cshtml",
- "~/CustomViewLocation/{1}/{0}.cshtml"
- };
- }
- public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
- {
- return base.FindView(controllerContext, viewName, masterName, useCache);
- }
- }
- }
我使用开发语言是C#,视图是Razor,所以稍稍修改了下ViewLocationFormats,让寻址路径能够寻到CustomViewLocation下面的视图。
接下去就很简单了,只需要把原来的视图引擎清空,加载自己的视图引擎就可以了。
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- ViewEngines.Engines.Clear();
- ViewEngines.Engines.Add(new CustomViewEngine());
- RegisterGlobalFilters(GlobalFilters.Filters);
- RegisterRoutes(RouteTable.Routes);
- }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本