0

これが私が推測する「主な質問」です

非常に早い段階で(HttpHandlerまたはHttpModuleを介して)要求を取得し、標準コントロールまたはユーザー/カスタムコントロールの形式で標準のasp.netマークアップを挿入し、フレームワークに処理させる「.NETの方法」はありますか?動的にコンパイルしているページのようですか?

その他の背景

さて、私たちが使用しているこのカスタムCMSは、かなり複雑なサイトを構築するのに最適です。優れたテンプレートシステム、ユーザー権限、インストールのしやすさなどがあります。ただし、追加したい機能の1つは、動的コンテンツを追加できることです。

CMSが出て「そのこと」を実行した後、結果は本質的に巨大なHTML文字列になり、応答で返送されます。レンダリングエンジンは、この「cmsのもの」を処理するクラスに含まれています。現在、これは標準のページライフサイクルで発生しますが、個別に呼び出すことができない理由はありません。

httpHandlerとhttpModuleの両方に近づくことができましたが、問題は、「cms html文字列」を取得し、独自の.netコントロールを追加して、フレームワークに新しいものを取得させることです。文字列を作成し、そこからコントロールツリーを構築します(ビューステートなどとともに)。

私が得た最も近いものは、PreRequestHandlerExecute中にResponseにフィルターをアタッチしたHttpModuleを使用したものでした。このフィルターは、{{replaceme}}をラベルタグマークアップに置き換える場所を探しました(概念実証...以下の例として)。これは、コントロールツリーが作成される前に読んだことから機能すると思いましたが、発生したのはasp.netマークアップがページに書き込まれたことだけでした(.NETではレンダリングされませんでした)。

私が試したもう1つのことは、HttpHandlerを介して完全に制御することです。これもほぼ同様に機能しました(以下の例もあります)...ここでの問題は、独自のコントロールツリーを構築し、ascxコントロールを実行することもできますが、これらすべてをマージする場所がないことです(すでに覚えていますhtmlドキュメント文字列全体があります。実行時にマージして.NETに渡そうとしています)。

私は非常に近いように感じますが、この作業のほとんどを.NETに渡すための非常に簡単な方法がありません...

Httpmodule

    private void PreRequestHandlerExecute(Object source, EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;

        context.Response.Filter = new PageFilter(context.Response.Filter);
    }

フィルタ(SOの例から)

    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);
    }
4

1 に答える 1

1

これを行おうとすると、多くの問題が発生する可能性があります。私があなたを理解しているなら、あなたはCMSから出てくるHTMLのチャンクを持っていて、それをコントロールツリーに戻したいと思っています。コントロールツリーは(ASP.Netマークアップからの)より多くのコントロールとマージして、最終的なHTMLを生成できます。 。

しかし、それはASP.Netが行うことの反対です。ASP.Netコントロールでマークアップを解析してコントロールツリーを生成し、そのコントロールツリーからHTMLを生成します。ASP.Netには、任意のHTMLを解析するものはありません。.aspxハンドラーを完全に書き直して、そのすべての解析関数とツリー構築関数を複製する必要があると思います。

私はあなたのCMSを使ってこれを実装する別の方法を見つけようとします。あなたはシステムを破壊している、そしてそれは混乱を維持するのが非常に難しいことにつながるだけかもしれない。

于 2012-04-03T21:31:22.283 に答える