これが私が推測する「主な質問」です:
非常に早い段階で(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);
}