假设下面的代码:
public class DynamicAspxHandler : IHttpHandler {
bool IHttpHandler.IsReusable { get { return false; } }
void IHttpHandler.ProcessRequest(HttpContext httpContext) {
string aspxContent = PlainASPXContent();
Page page = CreatePage(httpContext, aspxContent);
page.ProcessRequest(httpContext);
}
Page CreatePage(HttpContext context, string aspxContent) {
// How to implement this?
}
}
如何 实现CreatePage 方法,根据ASPX的纯字符串内容实例化页面?
注意,ASPX字符串本身可能包含对磁盘上现有MasterPage的引用。
我意识到这一点必然存在巨大的性能问题,但在这个阶段我只想知道如何做到这一点。显然我必须缓存结果。
感谢。
答案 0 :(得分:9)
您尝试关闭的路径实际上是从Web服务器文件系统以外的其他存储机制加载ASPX文件。您已经开始实现其中的一部分,但实际上您甚至不需要自定义HttpHandler来执行此操作 - ASP.NET具有指定实际ASPX标记的其他来源的现有机制。
它被称为VirtualPathProvider,它允许您交换默认功能以从磁盘加载文件,例如,从SQL Server加载它们或其他任何有意义的地方。然后,您可以利用ASP.NET自己使用的所有内置编译和缓存。
该功能的核心在于GetFile method和VirtualFile's Open():
public override VirtualFile GetFile(string virtualPath)
{
//lookup ASPX markup
return new MyVirtualFile(aspxMarkup);
}
//...
public class MyVirtualFile : VirtualFile
{
private string markup;
public MyVirtualFile(string markup)
{
this.markup = markup;
}
public override Stream Open()
{
return new StringReader(this.markup);
}
}
请注意,今天使用自定义VirtualPathProvider确实需要完全信任。但是,很快ASP.NET 4.0将可用,它支持中等信任的VPP。
答案 1 :(得分:1)
这样做的一种方法是创建VirtualPathProvider的子类,并通过调用HostingEnvironment.RegisterVirtualPathProvider将其设置为HostingEnvironment.VirtualPathProvider。您必须覆盖一些方法。最重要的是GetFile()。构建系统将负责缓存。