【问题标题】:Caching child user control only仅缓存子用户控件
【发布时间】:2012-10-01 04:35:30
【问题描述】:

有父用户控件,如下所示。

<%@ 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有pulic属性MatchDescription,在父控件的Page_Load中设置。我想缓存多个版本的子控件,基于MatchDescription 属性。

问题是,MatchDescription 属性不能在 Page_Load 中设置,因为子控件的缓存副本一旦可用就会被使用。

我该如何解决这个问题?

谢谢!

【问题讨论】:

  • MatchDescription 的值从何而来?比如,父页面是否从Url获​​取,然后在子控件上设置属性?
  • 感谢您的浏览! MatchDescription 的值来自 Parent 用户控件。不,它不是来自页面(不是来自查询字符串)
  • 没问题 ;) 您能否提供有关父控件从何处获取值的更多详细信息?如果我知道这段数据何时何地可用,我会更容易解决这个问题。
  • 在父用户控件中调用服务,该服务返回上一场比赛的 MatchDescription。

标签: asp.net caching user-controls outputcache


【解决方案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;
}

参考资料:

我的回答灵感来自:Any way to clear/flush/remove OutputCache?

我在这个问题中找到了Pre_Init 提示: Output Caching - GetVaryByCustomString based on value set in PageLoad()

这篇知识库文章讨论了为什么 PartialCachingControl.CachedControl 属性总是可以返回 null: http://support.microsoft.com/kb/837000

【讨论】:

    猜你喜欢
    • 2011-03-03
    • 2018-12-24
    • 2010-10-08
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多