1

以下に示すように、親ユーザー コントロールがあります。

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TestUserControl.ascx.cs" Inherits="TestUserControl" %>
<%@ Register Src="~/UserControls/ChildUserControl.ascx" TagName="ChildUserControl" TagPrefix="FLI" %>
<div>    
    <FLI:ChildUserControl ID="child1" runat="server"/>    
</div>

子 usecontrol には、親コントロールの でMatchDescription設定される pulic プロパティがあります。Page_Loadプロパティに基づいて、子コントロールの複数のバージョンをキャッシュしたいと考えていMatchDescriptionます。

問題は、子コントロールのキャッシュされたコピーが使用可能になると使用されるため、MatchDescriptionプロパティを に設定できないことです。Page_Load

この問題を解決するにはどうすればよいですか?

ありがとう!

4

1 に答える 1

1

使用GetVaryByCustomStringする方法はここにあるようです。私の概念実証は、次のもので構成されていました。

  • WebUserControl.ascx: テスト コントロール。単一のパブリック プロパティがありますMatchDescription
  • Global.asax:GetVaryByCustomStringメソッドをオーバーライドします。
  • WebForm.aspx: コントロールをホストする単純なフォーム。

WebUserControl.ascx

コントロールのマークアップに次を追加します。

<%@ OutputCache Duration="120" VaryByParam="none" VaryByCustom="MatchDescription" %>

これは、コントロールをキャッシュする期間 (秒単位) をVaryByCustom="MatchDescription"指定し、キャッシュするパラメーターの名前を指定します。

WebUserControl.ascx.cs

public partial class WebUserControl1 : System.Web.UI.UserControl
{
    public string MatchDescription { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        object description = this.Context.Application["MatchDescription"];

        if (description != null)
        {
            this.MatchDescription = description.ToString();
        }
        else
        {
            this.MatchDescription = "Not set";
        }

        Label1.Text = "Match description: " + this.MatchDescription;
    }
}

これにより、値の存在がチェックされMatchDescriptionます。親ページのコードの動作方法により、「設定されていません」と表示されることはありませんが、実装では値が設定されていない場合にのみ役立つ場合があります。

Global.asax

プロジェクトにファイルを追加Global.asaxし、次のメソッドを追加します。

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (custom == "MatchDescription")
    {
        object description = context.Application["MatchDescription"];

        if (description != null)
        {
            return description.ToString();
        }
    }

    return base.GetVaryByCustomString(context, custom);
}

MatchDescriptionこれは、キャッシュされたコントロールに関連付けられているかどうかをチェックするビットです。見つからない場合、コントロールは通常どおり作成されます。context.Application親ページ、ユーザー コントロール、global.asax ファイルの間で説明値をやり取りする方法が必要なため、これが使用されます。

WebForm.aspx.cs

public partial class WebForm : System.Web.UI.Page
{
    private static string[] _descriptions = new string[]
    {
        "Description 1",
        "Description 2",
        "Description 3",
        "Description 4"
    };

    protected override void OnPreInit(EventArgs e)
    {
        //Simulate service call.
        string matchDescription = _descriptions[new Random().Next(0, 4)];
        //Store description.
        this.Context.Application["MatchDescription"] = matchDescription;

        base.OnPreInit(e);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        var control = LoadControl("WebUserControl.ascx") as PartialCachingControl;
        this.Form.Controls.Add(control);

        //Indicate whether the control was cached.
        if (control != null)
        {
            if (control.CachedControl == null)
            {
                Label1.Text = "Control was cached";
            }
            else
            {
                Label1.Text = "Control was not cached";
            }
        }
    }
}

このコードでは、OnPreInitメソッドでサービス呼び出しを作成/シミュレートしていることに注意してください。GetVaryByCustomStringこれは、メソッドの前のページ ライフサイクルで発生するため必要です。

Page_Loadたとえば、コントロールがキャッシュされている場合、メソッドでアクセスするには、次の形式のコードが必要になることに注意してください。

    if (control is PartialCachingControl &&
        ((PartialCachingControl)control).CachedControl =!= null)
{
    WebUserControl1 userControl = (WebUserControl1)((PartialCachingControl)control).CachedControl;
}

参考文献:

私の答えは次のものに触発されました:OutputCacheをクリア/フラッシュ/削除する方法はありますか?

Pre_Initこの質問でヒント を見つけました:出力キャッシュ - PageLoad() で設定された値に基づく GetVaryByCustomString

この KB 記事では、PartialCachingControl.CachedControlプロパティが常に null を返す理由について説明しています: http://support.microsoft.com/kb/837000

于 2012-10-19T08:46:50.940 に答える