VirtualPathProvider 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
提供了一组方法,使 Web 应用程序可以从虚拟文件系统中检索资源。
public ref class VirtualPathProvider abstract : MarshalByRefObject
public abstract class VirtualPathProvider : MarshalByRefObject
type VirtualPathProvider = class
inherit MarshalByRefObject
Public MustInherit Class VirtualPathProvider
Inherits MarshalByRefObject
- 继承
示例
下面的代码示例是一个 VirtualPathProvider 类实现,它使用 存储在 对象中 DataSet 的信息创建虚拟文件系统。 该代码示例与 和 VirtualDirectory 类的代码示例VirtualFile一起提供加载到 DataSet 对象的数据存储中的虚拟资源。
此示例包含四个部分: VirtualPathProvider 类实现、用于填充 DataSet 对象的 XML 数据文件、 AppStart
包含 AppInitialize
用于向编译系统注册 VirtualPathProvider 类的方法的对象,以及提供指向虚拟文件的链接的 ASP.NET 页。
若要在应用程序中使用此示例代码,请执行以下步骤。
在 Web 服务器上创建示例应用程序。
复制自定义 VirtualPathProvider 对象的源代码, (请参阅下面的) 到应用程序目录中的
App_Code
文件中。复制自定义 VirtualDirectory 对象的源代码 (请参阅类概述主题中的 VirtualDirectory 示例部分,) 到应用程序目录中的
App_Code
文件中。复制自定义 VirtualFile 对象的源代码 (请参阅类概述主题中的 VirtualFile 示例部分,) 到应用程序目录中的
App_Code
文件中。复制对象的源代码
AppStart
, (请参阅下面的) 到应用程序目录中的App_Code
文件中。将 xml 数据 (下面的) 复制到应用程序目录中名为
XMLData.xml
的App_Data
文件中。将
default.aspx
文件 (参阅下面的) 复制到示例应用程序的根目录中。 使用 Web 浏览器打开default.aspx
文件,然后单击页面上的链接以查看虚拟文件的内容。
第一个示例是自定义 VirtualPathProvider 类。 DirectoryExists将重写 和 FileExists 方法,以指示虚拟文件系统中是否存在请求的目录。 GetDirectory将重写 和 GetFile 方法,以返回包含虚拟文件系统中信息的自定义 VirtualDirectory 和 VirtualFile 实例。
类还提供 GetVirtualData
和 VirtualFile 类用来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 数据用于演示如何使用 VirtualPathProvider、 VirtualDirectory和 VirtualFile 对象从外部数据检索数据,并且不用于表示生产质量的数据存储。
<?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_Code
、App_GlobalResources
、任何App_LocalResources
。应用程序数据文件夹
App_Data
。
注意
如果为部署预编译网站,则不会编译实例提供 VirtualPathProvider 的内容,并且预编译站点不会使用任何 VirtualPathProvider 实例。
注册 VirtualPathProvider
在 Web 应用程序执行任何页面分析或编译之前,应使用 HostingEnvironment.RegisterVirtualPathProvider 方法向 ASP.NET 编译系统注册自定义VirtualPathProvider实例。
通常,VirtualPathProvider实例在 目录中定义的方法中AppInitialize
App_Code
注册,或在 文件中的 Application_Start
事件Global.asax
期间注册。 有关在方法中AppInitialize
注册VirtualPathProvider实例的示例,请参阅示例部分。
可以在其他事件期间注册 VirtualPathProvider 实例,但在注册实例之前 VirtualPathProvider 编译和缓存的页面不会失效,即使新 VirtualPathProvider 实例现在将提供以前编译的页的源也是如此。
实施者说明
从 VirtualPathProvider继承时,必须重写以下成员:
如果自定义 VirtualPathProvider 类支持虚拟文件系统中的目录,则必须重写以下成员。
-
注意:如果虚拟文件系统通过创建虚拟
App_Themes
目录) 包含网站 (的主题,则自定义 VirtualPathProvider 类必须支持目录。自定义 VirtualPathProvider 类适用于派生自 VirtualFile 和 VirtualDirectory 类的类。 应从这些类型实现派生类,以提供虚拟文件系统中的文件和目录信息。 有关自定义 VirtualFile 实现的示例,请参阅类概述主题的示例 VirtualFile 部分。 有关自定义 VirtualDirectory 实现的示例,请参阅类概述主题的示例 VirtualDirectory 部分。
构造函数
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) |