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.xml 的檔案複製到應用程式目錄中的 App_Data 檔案中。

  7. 將檔案 default.aspx 複製到範例應用程式的根目錄中, (如下所示) 。 使用網頁瀏覽器開啟 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

第二個範例是 XML 資料檔案,用來填入 DataSet 自訂 VirtualPathProvider 物件所傳回的物件。 此 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 應用程式期間呼叫,以執行所需的任何自訂初始化。 在此情況下,它會向 ASP.NET 建置系統註冊自訂 VirtualPathProvider 物件。

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 應用程式執行任何頁面剖析或編譯之前,應該使用 HostingEnvironment.RegisterVirtualPathProvider 方法來向 ASP.NET 編譯系統註冊自訂 VirtualPathProvider 實例。

一般而言, VirtualPathProvider 實例會在 AppInitialize 目錄中定義的 App_Code 方法中註冊,或在檔案中的 Global.asax 事件期間 Application_Start 註冊。 如需在方法中 AppInitialize 註冊 VirtualPathProvider 實例的範例,請參閱一節。

您可以在其他事件期間註冊 VirtualPathProvider 實例,但在註冊實例之前 VirtualPathProvider 編譯和快取的頁面將不會失效,即使新的 VirtualPathProvider 實例現在會提供先前編譯頁面的來源也一樣。

給實施者的注意事項

當您繼承自 VirtualPathProvider 時,必須覆寫下列成員:

如果您的自訂 VirtualPathProvider 類別支援虛擬檔案系統中的目錄,您必須覆寫下列成員。

建構函式

VirtualPathProvider()

初始化這個類別,以供繼承的類別執行個體使用。 此建構函式只能由繼承的類別呼叫。

屬性

Previous

取得編譯系統中先前註冊 VirtualPathProvider 物件的參考。

方法

CombineVirtualPaths(String, String)

將基底路徑與相對路徑組合,以傳回虛擬資源的完整路徑。

CreateObjRef(Type)

建立包含所有相關資訊的物件,這些資訊是產生用來與遠端物件通訊的所需 Proxy。

(繼承來源 MarshalByRefObject)
DirectoryExists(String)

取得值,指出目錄是否存在於虛擬檔案系統中。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
FileExists(String)

取得值,指出檔案是否存在於虛擬檔案系統中。

GetCacheDependency(String, IEnumerable, DateTime)

基於指定的虛擬路徑建立快取相依性。

GetCacheKey(String)

傳回用於指定虛擬路徑的快取索引鍵。

GetDirectory(String)

從虛擬檔案系統取得虛擬目錄。

GetFile(String)

從虛擬檔案系統取得虛擬檔案。

GetFileHash(String, IEnumerable)

傳回指定虛擬路徑的雜湊。

GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetLifetimeService()
已淘汰.

擷取控制這個執行個體存留期 (Lifetime) 原則的目前存留期服務物件。

(繼承來源 MarshalByRefObject)
GetType()

取得目前執行個體的 Type

(繼承來源 Object)
Initialize()

初始化 VirtualPathProvider 執行個體。

InitializeLifetimeService()

藉由防止建立使用期,為 VirtualPathProvider 物件提供無限的存留期。

MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
MemberwiseClone(Boolean)

建立目前 MarshalByRefObject 物件的淺層複本。

(繼承來源 MarshalByRefObject)
OpenFile(String)

傳回虛擬檔案的資料流。

ToString()

傳回代表目前物件的字串。

(繼承來源 Object)

適用於