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 的信息创建虚拟文件系统。 该代码示例与代码示例一起使用,这些代码示例 VirtualFile 用于 VirtualDirectory 提供从加载到对象的数据存储中的 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 方法 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 数据用于演示如何使用VirtualPathProvider和VirtualDirectoryVirtualFile对象从外部数据检索数据,并且不打算表示生产质量的数据存储。
<?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 应用程序执行任何页面分析或编译之前,应使用 VirtualPathProvider 方法向 ASP.NET 编译系统注册自定义 HostingEnvironment.RegisterVirtualPathProvider 实例。
通常,VirtualPathProvider实例在AppInitialize目录中定义App_Code的方法或文件中的事件Application_Start中Global.asax注册。 有关在方法中VirtualPathProvider注册AppInitialize实例的示例,请参阅“示例”部分。
可以在其他事件期间注册 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) |