2012-10-10 53 views
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具有pulic財產MatchDescription,這是在父控件的Page_Load設置。我想要緩存基於MatchDescription屬性的子控件的多個版本。

問題是,MatchDescription屬性不能在Page_Load中設置,因爲子控件的緩存副本一旦可用就會被使用。

我該如何解決這個問題?

謝謝!

+0

哪裏了'MatchDescription'來自價值?例如,父頁面是否從Url獲​​取它,然後在子控件上設置屬性? –

+0

感謝您的光臨! MatchDescription的值來自Parent用戶控件。不,它不是來自頁面(不是來自查詢字符串) –

+0

沒問題;)您能否提供關於父控件從何處獲取值的更多細節?如果我知道這些數據何時何地可用,那麼解決這個問題會更容易。 –

回答

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 hi NT這樣一個問題: Output Caching - GetVaryByCustomString based on value set in PageLoad()

此知識庫文章討論爲什麼PartialCachingControl.CachedControl屬性可以隨時返回null: http://support.microsoft.com/kb/837000