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 的信息创建虚拟文件系统。 该代码示例与代码示例一起使用,这些代码示例 VirtualFile 用于 VirtualDirectory 提供从加载到对象的数据存储中的 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.xml 应用程序 App_Data 目录中的文件。

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

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

该类还提供一个 GetVirtualData 方法 VirtualDirectory ,供类 VirtualFile 用来访问 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.

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

  • 应用程序数据文件夹。 App_Data

注释

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

注册 VirtualPathProvider

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

通常,VirtualPathProvider实例在AppInitialize目录中定义App_Code的方法或文件中的事件Application_StartGlobal.asax注册。 有关在方法中VirtualPathProvider注册AppInitialize实例的示例,请参阅“示例”部分。

可以在其他事件期间注册 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)

适用于