上一篇介绍了VirtualPathProvider中虚拟文件的实现,参考:ASP.NET VirtualPathProvider (上)。
文件系统中,只有文件是不完整的,还要有目录。本篇介绍VirtualPathProvider中的虚拟目录实现。
实现代码:
首先定义了虚拟路径提供者,然后实现了虚拟文件和虚拟目录。值得一提的是,实现虚拟路径时,必须重载VirtualPathProvider的GetCacheDependency方法,可以实现自己的CacheDependency或直接返回null,否则会抛出找不到目录的异常。
运行截图:

文件系统中,只有文件是不完整的,还要有目录。本篇介绍VirtualPathProvider中的虚拟目录实现。
实现代码:
using System.Collections;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;
namespace Xianfen.Net.MyVirtualPathProvider_Directory
{
public class MyVirtualPathProvider : VirtualPathProvider
{
public static void AppInitialize()
{
HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider());
}
bool IsVirtualFile(string vPath)
{
return Regex.IsMatch(vPath, @".*vfile\d{1}\.aspx", RegexOptions.IgnoreCase);
}
bool IsVirtualDirectory(string vPath)
{
string relativePath = VirtualPathUtility.ToAppRelative(vPath);
return Regex.IsMatch(relativePath, @"~/vdir\d{1}/.*", RegexOptions.IgnoreCase);
}
public override bool FileExists(string virtualPath)
{
if (IsVirtualFile(virtualPath))
{
return true;
}
else
{
return Previous.FileExists(virtualPath);
}
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, System.DateTime utcStart)
{
if (IsVirtualFile(virtualPath))
{
return null;
}
else
{
return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
}
public override bool DirectoryExists(string virtualDir)
{
if (IsVirtualDirectory(virtualDir))
{
return true;
}
else
{
return base.DirectoryExists(virtualDir);
}
}
public override VirtualDirectory GetDirectory(string virtualDir)
{
if (IsVirtualDirectory(virtualDir))
{
return new MyVirtualDirectory(virtualDir);
}
else
{
return Previous.GetDirectory(virtualDir);
}
}
public override VirtualFile GetFile(string virtualPath)
{
virtualPath = virtualPath.ToLower();
if (IsVirtualFile(virtualPath))
{
return new MyVirtualFile(virtualPath);
}
else
{
return Previous.GetFile(virtualPath);
}
}
}
}
namespace Xianfen.Net.MyVirtualPathProvider_Directory
{
public class MyVirtualFile : VirtualFile
{
private string myPath;
public MyVirtualFile(string virtualPath)
: base(virtualPath)
{
myPath = virtualPath;
}
public override Stream Open()
{
Stream stream = new MemoryStream();
StreamWriter sw = new StreamWriter(stream);
StreamReader sr = null;
try
{
string content = File.ReadAllText(HttpContext.Current.Server.MapPath("~/App_Data/htm.txt"), Encoding.UTF8);
content = content.Replace("$currentfile$", myPath);
sw.Write(content);
sw.Flush();
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
finally
{
if (sr != null)
{
sr.Close();
sr.Dispose();
}
}
}
}
public class MyVirtualDirectory : VirtualDirectory
{
string vDir = null;
ArrayList children = new ArrayList();
ArrayList dirs = new ArrayList();
ArrayList files = new ArrayList();
public MyVirtualDirectory(string virtualDirectory)
: base(virtualDirectory)
{
vDir = virtualDirectory;
InitData();
}
private void InitData()
{
if (string.IsNullOrEmpty(vDir))
{
children.Add("vdir1");
children.Add("vdir2");
children.Add("vdir3");
children.Add("vdir4");
dirs.Add("vdir1");
dirs.Add("vdir2");
dirs.Add("vdir3");
dirs.Add("vdir4");
children.Add("vfile1.aspx");
children.Add("vfile2.aspx");
children.Add("vfile3.aspx");
children.Add("vfile4.aspx");
files.Add("vfile1.aspx");
files.Add("vfile2.aspx");
files.Add("vfile3.aspx");
files.Add("vfile4.aspx");
}
else
{
children.Add("vfile1.aspx");
children.Add("vfile2.aspx");
children.Add("vfile3.aspx");
children.Add("vfile4.aspx");
files.Add("vfile1.aspx");
files.Add("vfile2.aspx");
files.Add("vfile3.aspx");
files.Add("vfile4.aspx");
}
}
public override System.Collections.IEnumerable Children
{
get { return children; }
}
public override System.Collections.IEnumerable Directories
{
get { return dirs; }
}
public override System.Collections.IEnumerable Files
{
get { return files; }
}
}
}
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;
namespace Xianfen.Net.MyVirtualPathProvider_Directory
{
public class MyVirtualPathProvider : VirtualPathProvider
{
public static void AppInitialize()
{
HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider());
}
bool IsVirtualFile(string vPath)
{
return Regex.IsMatch(vPath, @".*vfile\d{1}\.aspx", RegexOptions.IgnoreCase);
}
bool IsVirtualDirectory(string vPath)
{
string relativePath = VirtualPathUtility.ToAppRelative(vPath);
return Regex.IsMatch(relativePath, @"~/vdir\d{1}/.*", RegexOptions.IgnoreCase);
}
public override bool FileExists(string virtualPath)
{
if (IsVirtualFile(virtualPath))
{
return true;
}
else
{
return Previous.FileExists(virtualPath);
}
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, System.DateTime utcStart)
{
if (IsVirtualFile(virtualPath))
{
return null;
}
else
{
return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
}
public override bool DirectoryExists(string virtualDir)
{
if (IsVirtualDirectory(virtualDir))
{
return true;
}
else
{
return base.DirectoryExists(virtualDir);
}
}
public override VirtualDirectory GetDirectory(string virtualDir)
{
if (IsVirtualDirectory(virtualDir))
{
return new MyVirtualDirectory(virtualDir);
}
else
{
return Previous.GetDirectory(virtualDir);
}
}
public override VirtualFile GetFile(string virtualPath)
{
virtualPath = virtualPath.ToLower();
if (IsVirtualFile(virtualPath))
{
return new MyVirtualFile(virtualPath);
}
else
{
return Previous.GetFile(virtualPath);
}
}
}
}
namespace Xianfen.Net.MyVirtualPathProvider_Directory
{
public class MyVirtualFile : VirtualFile
{
private string myPath;
public MyVirtualFile(string virtualPath)
: base(virtualPath)
{
myPath = virtualPath;
}
public override Stream Open()
{
Stream stream = new MemoryStream();
StreamWriter sw = new StreamWriter(stream);
StreamReader sr = null;
try
{
string content = File.ReadAllText(HttpContext.Current.Server.MapPath("~/App_Data/htm.txt"), Encoding.UTF8);
content = content.Replace("$currentfile$", myPath);
sw.Write(content);
sw.Flush();
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
finally
{
if (sr != null)
{
sr.Close();
sr.Dispose();
}
}
}
}
public class MyVirtualDirectory : VirtualDirectory
{
string vDir = null;
ArrayList children = new ArrayList();
ArrayList dirs = new ArrayList();
ArrayList files = new ArrayList();
public MyVirtualDirectory(string virtualDirectory)
: base(virtualDirectory)
{
vDir = virtualDirectory;
InitData();
}
private void InitData()
{
if (string.IsNullOrEmpty(vDir))
{
children.Add("vdir1");
children.Add("vdir2");
children.Add("vdir3");
children.Add("vdir4");
dirs.Add("vdir1");
dirs.Add("vdir2");
dirs.Add("vdir3");
dirs.Add("vdir4");
children.Add("vfile1.aspx");
children.Add("vfile2.aspx");
children.Add("vfile3.aspx");
children.Add("vfile4.aspx");
files.Add("vfile1.aspx");
files.Add("vfile2.aspx");
files.Add("vfile3.aspx");
files.Add("vfile4.aspx");
}
else
{
children.Add("vfile1.aspx");
children.Add("vfile2.aspx");
children.Add("vfile3.aspx");
children.Add("vfile4.aspx");
files.Add("vfile1.aspx");
files.Add("vfile2.aspx");
files.Add("vfile3.aspx");
files.Add("vfile4.aspx");
}
}
public override System.Collections.IEnumerable Children
{
get { return children; }
}
public override System.Collections.IEnumerable Directories
{
get { return dirs; }
}
public override System.Collections.IEnumerable Files
{
get { return files; }
}
}
}
首先定义了虚拟路径提供者,然后实现了虚拟文件和虚拟目录。值得一提的是,实现虚拟路径时,必须重载VirtualPathProvider的GetCacheDependency方法,可以实现自己的CacheDependency或直接返回null,否则会抛出找不到目录的异常。
运行截图:


分类:
ASP.NET
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?