飘遥的Blog

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

ASP.NET VirtualPathProvider (上)

Posted on 2008-11-13 13:59  Zzx飘遥  阅读(2275)  评论(1编辑  收藏  举报
在某些特殊的情况下,网站常规的文件、目录组织方式不能满足要求,在Asp.net 2.0提供了一些类来实现自己的虚拟文件系统,可以把网站文件保存在Zip文件里、保存在自己定制格式的二进制文件中甚至数据库中。这些类在System.Web.Hosting命名空间内定义,如:VirtualPathProvider、VirtualFile、VirtualDirectory等等。

以前实现页面或文件隐藏,可以继承IHttpHandler,IHttpModule,然后在web.comfig文件中配置,与之相比,VirtualPathProvider更强大。

可以映射到储在虚拟文件系统中的文件或文件夹包括:
ASP.NET 页、母版页、用户控件以及其他对象。
具有 .htm 和 .jpg 这样的扩展名的标准网页。
映射到 BuildProvider 实例的任何自定义扩展名。
App_Theme 文件夹中的任何命名主题。
 
但虚拟文件系统中不能存储下面的文件夹或文件:
Global.asax 文件。
Web.config 文件。
供 XmlSiteMapProvider 使用的站点地图数据文件。
包含或生成应用程序程序集的目录:Bin、App_Code、App_GlobalResources 以及任何 App_LocalResources 目录。
应用程序数据文件夹 App_Data。
 

1.定制自己的虚拟路径提供者
继承VirtualPathProvider类。
using System.IO;
using System.Web;
using System.Web.Hosting;
using System.Text;

namespace Xianfen.Net.MyVirtualPathProvider_File
{
    
public class MyVirtualPathProvider : VirtualPathProvider
    {
        
public override bool FileExists(string virtualPath)
        {
            virtualPath
= virtualPath.ToLower();

            
if (virtualPath.EndsWith("myvirtualfile.aspx"))
            {
                
return true;
            }
            
else
            {
                
return Previous.FileExists(virtualPath);
            }
        }

        
public override VirtualFile GetFile(string virtualPath)
        {
            virtualPath
= virtualPath.ToLower();

            
if (virtualPath.EndsWith("myvirtualfile.aspx"))
            {
                
return new MyVirtualFile(virtualPath);
            }
            
else
            {
                
return Previous.GetFile(virtualPath);
            }
        }
    }
}

2.定制自己的虚拟文件
继承VirtualFile类。
namespace Xianfen.Net.MyVirtualPathProvider_File
{
    
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
            {
                
if (myPath.EndsWith("myvirtualfile.aspx"))
                {
                    sr
= new StreamReader(
                        HttpContext.Current.Server.MapPath(
"~/App_Data/htm.txt"), Encoding.UTF8);
                }

                sw.Write(sr.ReadToEnd());
                sw.Flush();
                stream.Seek(
0, SeekOrigin.Begin);

                
return stream;
            }
            
finally
            {
                
if (sr != null)
                {
                    sr.Close();
                    sr.Dispose();
                }
            }
        }
    }
}

3.注册虚拟路径提供者。
注册方法有三种。
(1)AppInitialize这个特殊方法中注册:
public static void AppInitialize()
{
    HostingEnvironment.
        RegisterVirtualPathProvider(
new MyVirtualPathProvider());
}

(2)在Global.asax的Application_Start方法中注册。
protected void Application_Start(object sender, EventArgs e)
{
    HostingEnvironment.
        RegisterVirtualPathProvider(
new MyVirtualPathProvider());
}

(3)继承IHttpModule,在HttpApplication.BeginRequest的事件处理程序中注册。
public class MyIHttpModule : IHttpModule
{
    
public void Dispose()
    {
    }

    
public void Init(HttpApplication context)
    {
        context.BeginRequest
+= new EventHandler(context_BeginRequest);
    }

    
void context_BeginRequest(object sender, EventArgs e)
    {
        HostingEnvironment.
            RegisterVirtualPathProvider(
new MyVirtualPathProvider());
    }
}

web.config中配置:
<httpModules>
    
<add name="MyModule"
       type
="Xianfen.Net.MyVirtualPathProvider_File.MyIHttpModule, Xianfen.Net.MyVirtualPathProvider_File"/>
</httpModules>

运行可以看到能够找到虚拟文件。


参考资料:http://msdn.microsoft.com/zh-cn/library/system.web.hosting.virtualpathprovider.aspx

示例下载点击下载