1

.NET 4.0 および IIS 7 を使用して、クライアント用のデータベース エディター/基幹業務ツールを構築しています。セッションに保存した値に基づいて、ページに HTML を条件付きで含めたいと考えています。私はサーバー側でこれを行っており、コードをカプセル化するために、ASP サーバー コントロールを作成しました。

ご覧のとおり、サーバー コントロールによって生成されたマークアップは、私が期待したものではありません。誰かがこれを以前に見たことがあり、マークアップ生成の出力を制御する方法を理解するのに役立つことを願っています.

MyList というコントロールの新しい RenderContents を次に示します。<li> タグを使用して新しいリスト エントリを生成することになっています。

protected override void RenderContents(HtmlTextWriter output) {
    output.RenderBeginTag(HtmlTextWriterTag.Li);
    output.WriteEncodedText(this.Text);
    output.RenderEndTag();
}

メイン プロジェクトをコンパイルし、MyList への参照を追加した後、次の HTML で MyList を使用します。

<h1>Favorite Things</h1>
<ul>
    <cc1:MyList ID="mL1" runat="server" Text="Code that works!" />
    <cc1:MyList ID="mL2" runat="server" Text="Going home before 8" />
    <cc1:MyList ID="mL3" runat="server" Text="Cold drinks in fridge" />
</ul>

そして、以下を生成します。

<h1>Favorite Things</h1>
<ul>
    <span id="MainContent_mL1"><li>Code that works!</li></span>
    <span id="MainContent_mL2"><li>Going home before 8</li></span>
    <span id="MainContent_mL3"><li>Cold drinks in fridge</li></span>
</ul>

ここで、Session 値に基づいてテストを追加します。WebControl の Page プロパティは、コントロールのコンテナーへの参照を提供し、セッションへのアクセスを提供します。

protected override void RenderContents(HtmlTextWriter output) {
    string backcolor = "Yellow";
    if (this.Page.Session["access"] == null) {
        backcolor = "Red";
    }
    output.RenderBeginTag(HtmlTextWriterTag.Li);
    output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, backcolor);
    output.WriteEncodedText(this.Text);
    output.RenderEndTag();
}

ここで、マークアップが解明され始めます。「mL1」の矛盾に注意してください。

<h1>Favorite Things</h1>
<ul>
    <span id="MainContent_mL1"><li>Code that works!</li></span>
    <span id="MainContent_mL2" style="background-color:Red;"><li>Going home before 8</li></span>
    <span id="MainContent_mL3" style="background-color:Red;"><li>Cold drinks in fridge</li></span>
</ul>

spanより複雑な私の実際のコードでは、マークアップは単なるタグに変わりました。そして、ブレークポイントを設定すると、RenderContents()5 つのタグが連続しているときに 1 回しか呼び出されませんでした。

その他の情報: cc1:MyList コントロールのあるページには、EnableSession=true があります。私の web.config は、通常のセッション マネージャーを指定します (「rml」と「RoleBasedList」は、問題を切り分けてこの投稿を短くするために簡略化した「実際の」コントロールを参照します):

<system.web>
    <trace enabled="true" localOnly="false" pageOutput="true" requestLimit="20" />
    <compilation debug="true" targetFramework="4.0" />
    <pages>
        <controls>
            <add tagPrefix="rml" assembly="RoleBasedList" namespace="SOTS.ServerControls"/>
        </controls>
    </pages>
    <httpModules>
      <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
    </httpModules>

    <sessionState mode="InProc" cookieless="false" timeout="60"/>
    ...
</system.web>

そして今、あなたは私がするすべてを知っています!

4

2 に答える 2

1

WebControl.TagKeyカスタム サーバー コントロールのプロパティをオーバーライドするだけです。

protected override HtmlTextWriterTag TagKey
{
    get { return HtmlTextWriterTag.Li; }
}

デフォルト値はSpanで、表示内容を説明しています。もちろん、これを行うと、RenderContentsオーバーライドで Li タグをレンダリングしません。

別の方法として、 をオーバーライドRenderして、レンダリングを完全に制御するか、代わりに から派生させることができControlます。WebControlただし、 の機能の一部、特に外側のタグのスタイルが失われます。

あなたの2番目の問題に関して、あなたは電話しています:

output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, backcolor);

への次の呼び出しに適用されるスタイル属性を追加しますRenderBeginTag。を呼び出さないRenderBeginTagため、これはツリー内の次のコントロールのタグに適用されます。

もう 1 つのポイントはSession、コントロールが Visual Studio デザイナーでレンダリングされるときに null になることです。null を確認するか、代わりにデザイン モードで実行しているかどうかを確認する必要があります。

if ((Site != null) && (Site.DesignMode))
{
    ... running in design mode, Session won't be available
}
于 2012-09-22T17:50:06.263 に答える
0

避けてくださいSystem.Web.UI.WebControls。直接サブクラス化することをお勧めしますSystem.Web.UI.Control

派生元の<span>クラスによって挿入されています(言及していません)。RenderContentsの代わりにオーバーライドしていることに注意してください。つまり、コントロールのスーパークラスは、この場合Renderは の出力を自由にラップできます。RenderContents<span>

于 2012-09-22T14:31:26.340 に答える