VirtualPathProvider 类

定义

提供了一组方法,使 Web 应用程序可以从虚拟文件系统中检索资源。

public ref class VirtualPathProvider abstract : MarshalByRefObject
public abstract class VirtualPathProvider : MarshalByRefObject
type VirtualPathProvider = class
    inherit MarshalByRefObject
Public MustInherit Class VirtualPathProvider
Inherits MarshalByRefObject
继承
VirtualPathProvider

示例

下面的代码示例是一个 VirtualPathProvider 类实现,它使用 存储在 对象中 DataSet 的信息创建虚拟文件系统。 该代码示例与 和 VirtualDirectory 类的代码示例VirtualFile一起提供加载到 DataSet 对象的数据存储中的虚拟资源。

此示例包含四个部分: VirtualPathProvider 类实现、用于填充 DataSet 对象的 XML 数据文件、 AppStart 包含 AppInitialize 用于向编译系统注册 VirtualPathProvider 类的方法的对象,以及提供指向虚拟文件的链接的 ASP.NET 页。

若要在应用程序中使用此示例代码,请执行以下步骤。

  1. 在 Web 服务器上创建示例应用程序。

  2. 复制自定义 VirtualPathProvider 对象的源代码, (请参阅下面的) 到应用程序目录中的 App_Code 文件中。

  3. 复制自定义 VirtualDirectory 对象的源代码 (请参阅类概述主题中的 VirtualDirectory 示例部分,) 到应用程序目录中的 App_Code 文件中。

  4. 复制自定义 VirtualFile 对象的源代码 (请参阅类概述主题中的 VirtualFile 示例部分,) 到应用程序目录中的 App_Code 文件中。

  5. 复制对象的源代码 AppStart , (请参阅下面的) 到应用程序目录中的 App_Code 文件中。

  6. 将 xml 数据 (下面的) 复制到应用程序目录中名为 XMLData.xmlApp_Data 文件中。

  7. default.aspx 文件 (参阅下面的) 复制到示例应用程序的根目录中。 使用 Web 浏览器打开 default.aspx 文件,然后单击页面上的链接以查看虚拟文件的内容。

第一个示例是自定义 VirtualPathProvider 类。 DirectoryExists将重写 和 FileExists 方法,以指示虚拟文件系统中是否存在请求的目录。 GetDirectory将重写 和 GetFile 方法,以返回包含虚拟文件系统中信息的自定义 VirtualDirectoryVirtualFile 实例。

类还提供 GetVirtualDataVirtualFile 类用来VirtualDirectory访问DataSet包含虚拟文件系统数据的对象的方法。 在生产实现中,此方法通常在负责与数据存储交互的业务对象中实现。

using System;
using System.Data;
using System.Security.Permissions;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;

namespace Samples.AspNet.CS
{
  [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
  [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.High)]
  public class SamplePathProvider : VirtualPathProvider
  {
    private string dataFile;

    public SamplePathProvider()
      : base()
    {
    }

    protected override void Initialize()
    {
      // Set the datafile path relative to the application's path.
      dataFile = HostingEnvironment.ApplicationPhysicalPath + "App_Data\\XMLData.xml";
    }

    /// <summary>
    ///   Data set provider for the SampleVirtualDirectory and
    ///   SampleVirtualFile classes. In a production application
    ///   this method would be on a provider class that accesses
    ///   the virtual resource data source.
    /// </summary>
    /// <returns>
    ///   The System.Data.DataSet containing the virtual resources 
    ///   provided by the SamplePathProvider.
    /// </returns>
    public DataSet GetVirtualData()
    {
      // Get the data from the cache.
      DataSet ds = (DataSet)HostingEnvironment.Cache.Get("VPPData");
      if (ds == null)
      {
        // Data not in cache. Read XML file.
        ds = new DataSet();
        ds.ReadXml(dataFile);

        // Make DataSet dependent on XML file.
        CacheDependency cd = new CacheDependency(dataFile);

        // Put DataSet into cache for maximum of 20 minutes.
        HostingEnvironment.Cache.Add("VPPData", ds, cd,
          Cache.NoAbsoluteExpiration,
          new TimeSpan(0, 20, 0),
          CacheItemPriority.Default, null);

        // Set data timestamp.
        DateTime dataTimeStamp = DateTime.Now;
        // Cache it so we can get the timestamp in later calls.
        HostingEnvironment.Cache.Insert("dataTimeStamp", dataTimeStamp, null,
          Cache.NoAbsoluteExpiration,
          new TimeSpan(0, 20, 0),
          CacheItemPriority.Default, null);
      }
      return ds;
    }

    /// <summary>
    ///   Determines whether a specified virtual path is within
    ///   the virtual file system.
    /// </summary>
    /// <param name="virtualPath">An absolute virtual path.</param>
    /// <returns>
    ///   true if the virtual path is within the 
    ///   virtual file sytem; otherwise, false.
    /// </returns>
    private bool IsPathVirtual(string virtualPath)
    {
      String checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
      return checkPath.StartsWith("~/vrdir", StringComparison.InvariantCultureIgnoreCase);
    }

    public override bool FileExists(string virtualPath)
    {
      if (IsPathVirtual(virtualPath))
      {
        SampleVirtualFile file = (SampleVirtualFile)GetFile(virtualPath);
        return file.Exists;
      }
      else
            {
                return Previous.FileExists(virtualPath);
            }
        }

    public override bool DirectoryExists(string virtualDir)
    {
      if (IsPathVirtual(virtualDir))
      {
        SampleVirtualDirectory dir = (SampleVirtualDirectory)GetDirectory(virtualDir);
        return dir.Exists;
      }
      else
            {
                return Previous.DirectoryExists(virtualDir);
            }
        }

    public override VirtualFile GetFile(string virtualPath)
    {
      if (IsPathVirtual(virtualPath))
        return new SampleVirtualFile(virtualPath, this);
      else
        return Previous.GetFile(virtualPath);
    }

    public override VirtualDirectory GetDirectory(string virtualDir)
    {
      if (IsPathVirtual(virtualDir))
        return new SampleVirtualDirectory(virtualDir, this);
      else
        return Previous.GetDirectory(virtualDir);
    }

    public override CacheDependency GetCacheDependency(
      string virtualPath, 
      System.Collections.IEnumerable virtualPathDependencies, 
      DateTime utcStart)
    {
      if (IsPathVirtual(virtualPath))
      {
        System.Collections.Specialized.StringCollection fullPathDependencies = null;

        // Get the full path to all dependencies.
        foreach (string virtualDependency in virtualPathDependencies)
        {
          if (fullPathDependencies == null)
            fullPathDependencies = new System.Collections.Specialized.StringCollection();

          fullPathDependencies.Add(virtualDependency);
        }
        if (fullPathDependencies == null)
          return null;

        // Copy the list of full-path dependencies into an array.
        string[] fullPathDependenciesArray = new string[fullPathDependencies.Count];
        fullPathDependencies.CopyTo(fullPathDependenciesArray, 0);
        // Copy the virtual path into an array.
        string[] virtualPathArray = new string[1];
        virtualPathArray[0] = virtualPath;

        return new CacheDependency(virtualPathArray, fullPathDependenciesArray, utcStart);
      }
      else
            {
                return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
            }
        }
  }
}

Imports System.Data
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.Caching
Imports System.Web.Hosting


Namespace Samples.AspNet.VB
  <AspNetHostingPermission(SecurityAction.Demand, Level:=AspNetHostingPermissionLevel.Medium), _
   AspNetHostingPermission(SecurityAction.InheritanceDemand, level:=AspNetHostingPermissionLevel.High)> _
  Public Class SamplePathProvider
    Inherits VirtualPathProvider

    Private dataFile As String

    Public Sub New()
      MyBase.New()
    End Sub

    Protected Overrides Sub Initialize()
      ' Set the datafile path relative to the application's path.
      dataFile = HostingEnvironment.ApplicationPhysicalPath & _
        "App_Data\XMLData.xml"
    End Sub

    '   Data set provider for the SampleVirtualFile and
    '   SampleVirtualDirectory classes. In a production application
    '   this method would be on a provider class that accesses
    '   the virtual resource data source.
    '   The System.Data.DataSet containing the virtual resources
    '   provided by the SamplePathProvider.
    Public Function GetVirtualData() As DataSet
      ' Get the data from the cache.
      Dim ds As DataSet
      ds = CType(HostingEnvironment.Cache.Get("VPPData"), DataSet)

      If ds Is Nothing Then
        ' Data set not in cache. Read XML file.
        ds = New DataSet
        ds.ReadXml(dataFile)

        ' Make DataSet dependent on XML file.
        Dim cd As CacheDependency
        cd = New CacheDependency(dataFile)

        ' Put DataSet into cache for maximum of 20 minutes.
        HostingEnvironment.Cache.Add("VPPData", ds, cd, _
         Cache.NoAbsoluteExpiration, _
         New TimeSpan(0, 20, 0), _
         CacheItemPriority.Default, Nothing)

        ' Set data timestamp.
        Dim dataTimeStamp As DateTime
        dataTimeStamp = DateTime.Now
        ' Cache it so we can get the timestamp in later calls.
        HostingEnvironment.Cache.Add("dataTimeStamp", dataTimeStamp, Nothing, _
          Cache.NoAbsoluteExpiration, _
          New TimeSpan(0, 20, 0), _
          CacheItemPriority.Default, Nothing)
      End If
      Return ds
    End Function

    Private Function IsPathVirtual(ByVal virtualPath As String) As Boolean
      Dim checkPath As String
      checkPath = VirtualPathUtility.ToAppRelative(virtualPath)
      Return checkPath.StartsWith("~/vrdir", StringComparison.InvariantCultureIgnoreCase)
    End Function

    Public Overrides Function FileExists(ByVal virtualPath As String) As Boolean
      If (IsPathVirtual(virtualPath)) Then
        Dim file As SampleVirtualFile
        file = CType(GetFile(virtualPath), SampleVirtualFile)
        Return file.Exists
      Else
        Return Previous.FileExists(virtualPath)
      End If
    End Function

    Public Overrides Function DirectoryExists(ByVal virtualDir As String) As Boolean
      If (IsPathVirtual(virtualDir)) Then
        Dim dir As SampleVirtualDirectory
        dir = CType(GetDirectory(virtualDir), SampleVirtualDirectory)
        Return dir.exists
      Else
        Return Previous.DirectoryExists(virtualDir)
      End If
    End Function

    Public Overrides Function GetFile(ByVal virtualPath As String) As VirtualFile
      If (IsPathVirtual(virtualPath)) Then
        Return New SampleVirtualFile(virtualPath, Me)
      Else
        Return Previous.GetFile(virtualPath)
      End If
    End Function

    Public Overrides Function GetDirectory(ByVal virtualDir As String) As VirtualDirectory
      If (IsPathVirtual(virtualDir)) Then
        Return New SampleVirtualDirectory(virtualDir, Me)
      Else
        Return Previous.GetDirectory(virtualDir)
      End If
    End Function

    Public Overrides Function GetCacheDependency(ByVal virtualPath As String, ByVal virtualPathDependencies As IEnumerable, ByVal utcStart As Date) As CacheDependency
      If (IsPathVirtual(virtualPath)) Then

        Dim fullPathDependencies As System.Collections.Specialized.StringCollection
        fullPathDependencies = Nothing

        ' Get the full path to all dependencies.
        For Each virtualDependency As String In virtualPathDependencies
          If fullPathDependencies Is Nothing Then
            fullPathDependencies = New System.Collections.Specialized.StringCollection
          End If

          fullPathDependencies.Add(virtualDependency)
        Next

        If fullPathDependencies Is Nothing Then
          Return Nothing
        End If

        Dim fullPathDependenciesArray As String()
        fullPathDependencies.CopyTo(fullPathDependenciesArray, 0)

        Return New CacheDependency(fullPathDependenciesArray, utcStart)
      Else
        Return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart)
      End If
    End Function
  End Class
End Namespace

第二个示例是用于填充 DataSet 自定义 VirtualPathProvider 对象返回的 对象的 XML 数据文件。 此 XML 数据用于演示如何使用 VirtualPathProviderVirtualDirectoryVirtualFile 对象从外部数据检索数据,并且不用于表示生产质量的数据存储。

<?xml version="1.0" encoding="utf-8" ?>  
  <resource type="dir"   
    path="/vrDir"   
    parentPath=""   
    content="">  
    <resource type="file"   
      path="/vrDir/Level1FileA.vrf"  
      parentPath="/vrDir"   
      content="This is the content of file Level1FileA.">  
    </resource>  
    <resource type="file"   
      path="/vrDir/Level1FileB.vrf"  
      parentPath="/vrDir"   
      content="This is the content of file Level1FileB.">  
    </resource>  
    <resource type="dir"   
      path="/vrDir/Level2DirA"   
      parentPath="/vrDir"   
      content="">  
    <resource type="file"   
      path="/vrDir/Level2DirA/Level2FileA.vrf"   
      parentPath="/vrDir/Level2DirA"   
      content="This is the content of file Level2FileA.">  
    </resource>  
    <resource type="file"   
      path="/vrDir/Level2DirA/Level2FileB.vrf"  
      parentPath="/vrDir/Level2DirA"   
      content="This is the content of file Level2FileB.">  
    </resource>  
  </resource>  
  <resource type="dir"   
    path="/vrDir/Level2DirB"   
    parentPath="/vrDir"   
    content="">  
    <resource type="file"   
      path="/vrDir/Level2DirB/Level2FileA.vrf"   
      parentPath="/vrDir/Level2DirB"   
      content="This is the content of file Level2FileA.">  
    </resource>  
    <resource type="file"   
      path="/vrDir/Level2DirB/Level2FileB.vrf"  
      parentPath="/vrDir/Level2DirB"   
      content="This is the content of file Level2FileB.">  
    </resource>  
  </resource>  
</resource>  

第三个示例提供了一个 AppStart 包含 方法的 AppInitialize 对象。 此方法在初始化 ASP.NET 应用程序期间调用,以执行所需的任何自定义初始化。 在这种情况下,它将自定义 VirtualPathProvider 对象注册到 ASP.NET 生成系统。

using System.Web.Hosting;

namespace Samples.AspNet.CS
{
  /// <summary>
  ///   Contains the application initialization method
  ///   for the sample application.
  /// </summary>
  public static class AppStart
  {
    public static void AppInitialize()
    {
      SamplePathProvider sampleProvider = new SamplePathProvider();
      HostingEnvironment.RegisterVirtualPathProvider(sampleProvider);
    } 
  }
}

Imports System.Web.Hosting

Namespace Samples.AspNet.VB

  Public Class AppStart

    Public Shared Sub AppInitialize()
      Dim sampleProvider As SamplePathProvider = New SamplePathProvider()
      HostingEnvironment.RegisterVirtualPathProvider(sampleProvider)
    End Sub

  End Class
End Namespace

最后一个示例是一个 ASP.NET 页,其中包含指向虚拟文件系统中包含的虚拟文件的链接。


<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <meta http-equiv="Content-Type" content="text/html" />
  <title>Virtual Path Provider Example</title>
</head>
<body>
  <form id="form1" runat="server">
    <asp:HyperLink ID="hyperLink1" runat="server" NavigateUrl="vrDir/Level1FileA.vrf" Text="Level 1, File A" /><br />
    <asp:HyperLink ID="hyperLink2" runat="server" NavigateUrl="vrDir/Level1FileB.vrf" Text="Level 1, File B" /><br />
    <asp:HyperLink ID="hyperLink3" runat="server" NavigateUrl="vrDir/Level2DirA/Level2FileA.vrf" Text="Level 2a, File A" /><br />
    <asp:HyperLink ID="hyperLink4" runat="server" NavigateUrl="vrDir/Level2DirA/Level2FileB.vrf" Text="Level 2a, File B" /><br />
    <asp:HyperLink ID="hyperLink5" runat="server" NavigateUrl="vrDir/Level2DirB/Level2FileA.vrf" Text="Level 2b, File A" /><br />
    <asp:HyperLink ID="hyperLink6" runat="server" NavigateUrl="vrDir/Level2DirB/Level2FileB.vrf" Text="Level 2b, File B" /><br />
  </form>
</body>
</html>
<%@ Page Language="VB" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <meta http-equiv="Content-Type" content="text/html" />
  <title>Virtual Path Provider Example</title>
</head>
<body>
  <form id="form1" runat="server">
    <asp:HyperLink ID="hyperLink1" runat="server" NavigateUrl="vrDir/Level1FileA.vrf" Text="Level 1, File A" /><br />
    <asp:HyperLink ID="hyperLink2" runat="server" NavigateUrl="vrDir/Level1FileB.vrf" Text="Level 1, File B" /><br />
    <asp:HyperLink ID="hyperLink3" runat="server" NavigateUrl="vrDir/Level2DirA/Level2FileA.vrf" Text="Level 2a, File A" /><br />
    <asp:HyperLink ID="hyperLink4" runat="server" NavigateUrl="vrDir/Level2DirA/Level2FileB.vrf" Text="Level 2a, File B" /><br />
    <asp:HyperLink ID="hyperLink5" runat="server" NavigateUrl="vrDir/Level2DirB/Level2FileA.vrf" Text="Level 2b, File A" /><br />
    <asp:HyperLink ID="hyperLink6" runat="server" NavigateUrl="vrDir/Level2DirB/Level2FileB.vrf" Text="Level 2b, File B" /><br />
  </form>
</body>
</html>

注解

VirtualPathProvider 提供了一组用于实现 Web 应用程序的虚拟文件系统的方法。 在虚拟文件系统中,文件和目录由服务器操作系统提供的文件系统以外的数据存储进行管理。 例如,可以使用虚拟文件系统将内容存储在SQL Server数据库中。

可以将根据请求处理的任何文件存储在虚拟文件系统中。 这包括:

  • ASP.NET 页、母版页、用户控件和其他对象。

  • 具有扩展(如.htm和.jpg)的标准网页。

  • 映射到 BuildProvider 实例的任何自定义扩展。

  • 文件夹中的任何命名主题 App_Theme

不能在虚拟文件系统中存储 ASP.NET 应用程序文件夹或生成应用程序级程序集的文件。 这包括:

  • Global.asax 文件。

  • Web.config文件。

  • 使用的 XmlSiteMapProvider站点地图数据文件。

  • 包含应用程序程序集或生成应用程序程序集的目录: BinApp_CodeApp_GlobalResources、任何 App_LocalResources

  • 应用程序数据文件夹 App_Data

注意

如果为部署预编译网站,则不会编译实例提供 VirtualPathProvider 的内容,并且预编译站点不会使用任何 VirtualPathProvider 实例。

注册 VirtualPathProvider

在 Web 应用程序执行任何页面分析或编译之前,应使用 HostingEnvironment.RegisterVirtualPathProvider 方法向 ASP.NET 编译系统注册自定义VirtualPathProvider实例。

通常,VirtualPathProvider实例在 目录中定义的方法中AppInitializeApp_Code注册,或在 文件中的 Application_Start 事件Global.asax期间注册。 有关在方法中AppInitialize注册VirtualPathProvider实例的示例,请参阅示例部分。

可以在其他事件期间注册 VirtualPathProvider 实例,但在注册实例之前 VirtualPathProvider 编译和缓存的页面不会失效,即使新 VirtualPathProvider 实例现在将提供以前编译的页的源也是如此。

实施者说明

VirtualPathProvider继承时,必须重写以下成员:

如果自定义 VirtualPathProvider 类支持虚拟文件系统中的目录,则必须重写以下成员。

构造函数

VirtualPathProvider()

初始化该类供继承的类实例使用。 此构造函数只能由继承的类调用。

属性

Previous

获取对编译系统中以前注册的 VirtualPathProvider 对象的引用。

方法

CombineVirtualPaths(String, String)

将基路径与相对路径组合,以返回某虚拟资源的完整路径。

CreateObjRef(Type)

创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。

(继承自 MarshalByRefObject)
DirectoryExists(String)

获取一个值,该值指示目录是否存在于虚拟文件系统中。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
FileExists(String)

获取一个值,该值指示文件是否存在于虚拟文件系统中。

GetCacheDependency(String, IEnumerable, DateTime)

基于指定的虚拟路径创建一个缓存依赖项。

GetCacheKey(String)

返回一个用于指定虚拟路径的缓存键。

GetDirectory(String)

从虚拟文件系统中获取一个虚拟目录。

GetFile(String)

从虚拟文件系统中获取一个虚拟文件。

GetFileHash(String, IEnumerable)

返回指定虚拟路径的哈希值。

GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetLifetimeService()
已过时.

检索控制此实例的生存期策略的当前生存期服务对象。

(继承自 MarshalByRefObject)
GetType()

获取当前实例的 Type

(继承自 Object)
Initialize()

初始化 VirtualPathProvider 实例。

InitializeLifetimeService()

通过阻止创建租约给予 VirtualPathProvider 对象无限的生存期。

MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
MemberwiseClone(Boolean)

创建当前 MarshalByRefObject 对象的浅表副本。

(继承自 MarshalByRefObject)
OpenFile(String)

从虚拟文件返回一个流。

ToString()

返回表示当前对象的字符串。

(继承自 Object)

适用于