以下是我猜的“主要问题”:
是否有一种“.NET方式”可以很早地获取请求(通过HttpHandler或HttpModule)并以标准控件或用户/自定义控件的形式注入标准的asp.net标记,并且框架将它视为一个动态编译的页面?
更多背景
好的,我们使用的这个自定义CMS可以很好地构建相当复杂的网站。它有一个很好的模板系统,用户权限,易于安装等。但是,我们要添加的一个功能是能够添加动态内容。
CMS退出并执行“它的事情”后,结果实际上是一个巨大的HTML字符串,在响应中被发回。渲染引擎包含在处理这个“cms stuff”的类中。现在这发生在标准页面生命周期中,但没有理由不能单独调用它。
我已经能够接近httpHandler和httpModule,但问题是我真正需要的是采用“cms html string”,添加我自己的.net控件,然后让框架接受新的字符串并从中构建一个控制树(以及viewstate等)。
我得到的最接近的是HttpModule,它在PreRequestHandlerExecute期间为Response附加了一个过滤器。此过滤器只是使用标签标记标记(作为概念验证...下面的示例)查找要替换{{replaceme}}的位置。我认为这可以工作,因为从我读到的这是在控制树创建之前,但所有发生的事情是asp.net标记被写入页面(不是由.NET呈现)。
我尝试过的另一件事是通过HttpHandler进行完全控制。这个几乎也可以工作(也是下面的例子)......这里的问题是,虽然我可以构建自己的控制树,甚至执行ascx控件,但是没有地方可以合并所有的这些东西在一起(记得我已经有一个完整的html文档字符串,我试图在运行时将它合并并传递给.NET)。
我觉得我非常接近,但却错过了将大部分工作交给.NET的一些非常简单的方法......
HTTP模块
private void PreRequestHandlerExecute(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Filter = new PageFilter(context.Response.Filter);
}
过滤(我认为是一个例子)
public override void Write(byte[] buffer, int offset, int count)
{
string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
// ---------------------------------
// Wait for the closing </html> tag
// ---------------------------------
Regex eof = new Regex("</html>", RegexOptions.IgnoreCase);
if (!eof.IsMatch(strBuffer))
{
responseHtml.Append(strBuffer);
}
else
{
responseHtml.Append(strBuffer);
string finalHtml = responseHtml.ToString();
finalHtml = finalHtml.Replace("{{replaceme}}", @"<asp:Label id=""lblMyTest"" runat=""server"" Text=""This is a label that was replaced by my responsefilter"" />");
// Transform the response and write it back out
byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);
responseStream.Write(data, 0, data.Length);
}
}
测试HttpHandler
public void ProcessRequest(HttpContext context)
{
MyBasePage page = new MyBasePage();
Test tpage = (Test)BuildManager.CreateInstanceFromVirtualPath("~/Test.ascx", typeof(Test));
var htmlform = new System.Web.UI.HtmlControls.HtmlForm();
var panel = new Panel();
panel.Controls.Add(new Label() { Text = "Hello World" });
panel.Controls.Add(tpage);
htmlform.Controls.Add(panel);
page.Controls.Add(htmlform);
page.ProcessRequest(context);
}
答案 0 :(得分:1)
尝试这样做可能会遇到很多麻烦。如果我理解你,你有一大堆来自CMS的HTML,你想把它变成一个控制树,你可以将它与更多的控件(来自ASP.Net标记)合并,然后生成最终的HTML
但这与ASP.Net的作用相反。它使用ASP.Net控件解析标记以生成控制树,然后从该控制树生成HTML。 ASP.Net中的任何内容都不会解析任意HTML。我认为您需要完全重写.aspx处理程序,复制其所有解析和树构建函数。
我会尝试使用您的CMS找到另一种方法来实现这一点。你破坏了系统,这只会导致很难维护。