将ASP标记和UserControl插入CMS内容

时间:2012-04-03 21:18:18

标签: c# asp.net httphandler httpmodule

以下是我猜的“主要问题”

是否有一种“.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);
    }

1 个答案:

答案 0 :(得分:1)

尝试这样做可能会遇到很多麻烦。如果我理解你,你有一大堆来自CMS的HTML,你想把它变成一个控制树,你可以将它与更多的控件(来自ASP.Net标记)合并,然后生成最终的HTML

但这与ASP.Net的作用相反。它使用ASP.Net控件解析标记以生成控制树,然后从该控制树生成HTML。 ASP.Net中的任何内容都不会解析任意HTML。我认为您需要完全重写.aspx处理程序,复制其所有解析和树构建函数。

我会尝试使用您的CMS找到另一种方法来实现这一点。你破坏了系统,这只会导致很难维护。