飘遥的Blog

C/C++/.NET
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ASP.NET VirtualPathProvider (下)

Posted on 2009-07-26 19:42  Zzx飘遥  阅读(1521)  评论(0编辑  收藏  举报
上一篇介绍了VirtualPathProvider中虚拟文件的实现,参考:ASP.NET VirtualPathProvider (上)
文件系统中,只有文件是不完整的,还要有目录。本篇介绍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; }
        }
    }
}

首先定义了虚拟路径提供者,然后实现了虚拟文件和虚拟目录。值得一提的是,实现虚拟路径时,必须重载VirtualPathProvider的GetCacheDependency方法,可以实现自己的CacheDependency或直接返回null,否则会抛出找不到目录的异常。

运行截图: