asp.net mvc RouteCollection的RouteExistingFiles属性理解
RouteCollectiond的RouteExistingFiles属性一看这个名字,我想大家就能猜出来它的意思,对静态资源是否启用路由。我在Asp.net Web.config文件读取路径你真的清楚吗? 里面做demo时遇到这样一个问题:
项目结构如下:
我原本是用来让程序读views/channel/men/web.config文件,当我添加了men文件夹后,整过路由都出错了。
我的路由代码:
routes.MapRoute("channelDefault", "{ChannelName}/{action}", new
{
controller = "Channel",
action = "Default"
});
controller代码:
public ActionResult Default()
{
string channelName = RouteData.Values["ChannelName"].ToString().Trim();
string actionName = RouteData.Values["action"].ToString().Trim();
string viewName = string.Format("{0}/{1}", channelName, actionName);
return View(viewName);
}
整个代码是不是都很简单啊。当我添加了men文件夹后路由出错,移除men路由就对了。那么问题也就找到了
routes.RouteExistingFiles = true;我对RouteExistingFiles树立的理解是:对已存在文件是否启用路由,其实这个理解有点不对啊。
让我们来看看RouteCollection的GetRouteData方法,里面有这么一段:
if (!this.RouteExistingFiles) { string appRelativeCurrentExecutionFilePath = httpContext.Request.AppRelativeCurrentExecutionFilePath; if (((appRelativeCurrentExecutionFilePath != "~/") && (this._vpp != null)) && (this._vpp.FileExists(appRelativeCurrentExecutionFilePath) || this._vpp.DirectoryExists(appRelativeCurrentExecutionFilePath))) { return null; } } using (this.GetReadLock()) { foreach (RouteBase base2 in this) { RouteData routeData = base2.GetRouteData(httpContext); if (routeData != null) { return routeData; } } }
它检查文件和文件目录是否存在。例如我的请求路径是http://localhost:11286/men,那么httpContext.Request.AppRelativeCurrentExecutionFilePath的取值是~/men/, 而men这个路径树存在的。所以及返回null了。我们知道在UrlRoutingModule的PostResolveRequestCache方法中 会调用this.RouteCollection.GetRouteData(context)获取RouteData,如果返回值不为null才会调用 context.RemapHandler(httpHandler),那么如果这里返回为null也就表示路由失败,那么也就找不到对应的 handler来处理此次请求了。
现在让我们来看看你HostingEnvironment.VirtualPathProvider是如果查找文件和路径的,首先我们要知道HostingEnvironment.VirtualPathProvider其实是一个MapPathBasedVirtualPathProvider实例,
public override bool DirectoryExists(string virtualDir)
{
return this.CacheLookupOrInsert(virtualDir, false);
}
public override bool FileExists(string virtualPath)
{
return this.CacheLookupOrInsert(virtualPath, true);
}
从DirectoryExists和FileExists方法来看,它主要是调用了一个CacheLookupOrInsert方法。
private bool CacheLookupOrInsert(string virtualPath, bool isFile) { string physicalPath = HostingEnvironment.MapPathInternal(virtualPath); bool doNotCacheUrlMetadata = CachedPathData.DoNotCacheUrlMetadata; string key = null; if (!doNotCacheUrlMetadata) { key = this.CreateCacheKey(isFile, physicalPath); bool? nullable = HttpRuntime.CacheInternal[key] as bool?; if (nullable.HasValue) { return nullable.Value; } } bool flag2 = isFile ? File.Exists(physicalPath) : Directory.Exists(physicalPath); if (!doNotCacheUrlMetadata) { CacheDependency dependencies = null; string filename = flag2 ? physicalPath : FileUtil.GetFirstExistingDirectory(AppRoot, physicalPath); if (filename != null) { dependencies = new CacheDependency(filename); TimeSpan urlMetadataSlidingExpiration = CachedPathData.UrlMetadataSlidingExpiration; HttpRuntime.CacheInternal.UtcInsert(key, flag2, dependencies, Cache.NoAbsoluteExpiration, urlMetadataSlidingExpiration); } } return flag2; } |
这里其中有string physicalPath = HostingEnvironment.MapPathInternal(virtualPath);这句,就是把虚拟路径转化为物理路径的。例如我实验 的时候virtualPath=~/men/,而physicalPath=C:\Users\majiang\Documents\Visual Studio 2010\Projects\System.Configuration\MvcApp\men\,这个文件没有但是目录却是有的。顺便提一下默认情况下 CachedPathData.DoNotCacheUrlMetadata是false,在这里它主要用来控制是否使用缓存。真正查找文件和目录是否存 在是在这句代码完成的:
bool flag2 = isFile ? File.Exists(physicalPath) : Directory.Exists(physicalPath);不过大家一定要注意这里默认是有缓存的,我当时做实验的时候见 了 routes.RouteExistingFiles = true;这句也没起到作用,就知道缓存的存在,知道这里在明白缓存是怎么搞的啊。
总结一下吧:RouteCollectiond的RouteExistingFiles属性是:对已存在的文件和文件夹是否启用路由,大家千万不要忘记还有文件夹这个检查,同时文件和文件夹的检查结果默认是启用了缓存的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构