Варьируется свойствами элемента управления с использованием PartialCaching в ASP.NET - PullRequest
11 голосов
/ 19 мая 2009

Я использую атрибут PartialCaching в базовом классе пользовательского элемента управления.

Я бы хотел, чтобы кэшированные элементы управления менялись в зависимости от свойств, установленных для экземпляра элемента управления.

Например:

<mycontrols:control1 runat="server" param1="10" param2="20" />

... выходные данные будут кэшироваться отдельно от экземпляра элемента управления с другими свойствами:

<mycontrols:control1 runat="server" param1="15" param2="20" />

... и этот элемент управления также будет кэшироваться отдельно:

<mycontrols:control1 runat="server" param1="10" param2="25" />

Однако, если два экземпляра элемента управления на двух отдельных страницах имеют идентичные свойства param1 и param2, я бы хотел, чтобы они кэшировались как один объект (чтобы кэшированный элемент управления был общим).

Можно ли реализовать описанный выше вариант использования с помощью атрибута PartialCaching? Какие настройки я бы использовал? varyByControl

Кроме того, возможно ли сделать переменную длительности кэша во время выполнения?

Спасибо.

Ответы [ 3 ]

22 голосов
/ 24 мая 2009

Чтобы ответить на ваш первый вопрос, позвольте мне сначала сказать вам, что на ваш вопрос есть ответ;). «Shared» ... да, это ключевое слово :) Чтобы иметь один экземпляр в кэше для пользовательского элемента управления на всех страницах, установите Shared = 'true' в директиве @OutputCache. Это должно быть установлено на уровне управления пользователем, то есть на странице ascx.

Чтобы кэшировать пользовательский элемент управления на основе свойств пользовательского элемента управления, необходимо указать полное имя свойства в разделе varByControls PartialCachingAttribute. Несколько свойств, если они есть, должны быть разделены точками с запятой.

<%@ Control Language="C#" AutoEventWireup="true" 
CodeFile="WebUserControl.ascx.cs" 
Inherits="UC_WebUserControl" %>
<%@ OutputCache Duration="60" 
VaryByControl="UC_WebUserControl.param1;UC_WebUserControl.param2" 
VaryByParam="none" Shared="true" %>

или вы также можете включить атрибут PartialCache для пользовательского элемента управления:

[PartialCaching(60, null, "UC_WebUserControl.param1;UC_WebUserControl.param2", null, true)]
public partial class UC_WebUserControl : System.Web.UI.UserControl
{
    public string param1 { get; set; }
    public string param2 { get; set; }

}

ИЛИ другой способ кэширования элемента управления на комбинации обоих значений:

[PartialCaching(60, null, "UC_WebUserControl.BothParams", null, true)]
public partial class UC_WebUserControl : System.Web.UI.UserControl
{
    public string param1 { get; set; }
    public string param2 { get; set; }

    public string BothParams    
    {
        get { return String.Concat(param1, param2); }
    }

}

Последний параметр (true) указывает общий доступ. Длительность указана как 60. См. Ссылку Как: кэшировать несколько версий пользовательского элемента управления на основе параметров

Чтобы ответить на ваш второй вопрос, чтобы установить длительность кэша для пользовательской управляющей переменной во время выполнения, вы можете сделать это двумя способами:

  1. Назначьте его в пользовательском коде управления:

    [PartialCaching(60, null, "UC_WebUserControl.BothParams", null, true)]
    public partial class WebUserControl1 : System.Web.UI.UserControl
    {
        ...
        protected void Page_Load(object sender, EventArgs e)
        {
            this.CachePolicy.Duration = new TimeSpan(0, 0, 60);
        }    
    }
  2. Вы можете назначить его в коде страницы, на которую ссылается пользовательский элемент управления, используя идентификатор пользовательского элемента управления.

например. Если пользовательский элемент управления aspx:

<mycontrols:control1 ID="ucControl1" runat="server" param1="15" param2="20" />

тогда в коде aspx вы должны написать:

this.ucControl1.CachePolicy.Duration = new TimeSpan(0, 0, 60);

К вашему сведению, если и пользовательский элемент управления, и страница кэшированы: если длительность кэша вывода страницы меньше, чем у пользовательского элемента управления, пользовательский элемент управления будет кэшироваться до истечения его продолжительности, даже после того, как остальная часть страницы будет регенерируется по запросу. Например, если для кэширования вывода страницы установлено значение 50 секунд, а для кэширования вывода пользовательского элемента управления установлено значение 100 секунд, срок действия пользовательского элемента управления истекает один раз каждые два раза, когда истекает срок действия остальной части страницы.

1 голос
/ 12 сентября 2014

Я отправляю новый ответ на этот очень старый вопрос, потому что принятый ответ является крайне неточным. Правильный ответ:

  • Нет встроенного способа изменить значение свойства элемента управления. VaryByControl работает только для элементов управления.
  • Когда обслуживается кэшированная версия, ваше поле управления будет нулевым. Вы не можете изменить длительность кэша в коде - вы получите исключение NullReferenceException.
  • Существует ошибка, которая изменяет кэш в зависимости от идентификатора элемента управления и идентификатора (ов) NamingContainer, если для VaryByControl установлено любое значение. Вот почему, кажется, иногда работает. Ошибка прямо здесь: http://referencesource.microsoft.com/#System.Web/xsp/system/Web/UI/PartialCachingControl.cs#530

Недавно я писал об этом прямо здесь: http://tabeokatech.blogspot.be/2014/09/outputcache-on-user-controls.html.

Способ, которым вы могли бы выполнить эту работу, - это вызвать метод построителя PartialCachingControl самостоятельно в коде и вставить значение свойства, которое вы хотите изменить, в параметре guid:

    // PhControls is an asp:PlaceHolder
    protected void Page_Init(object sender, EventArgs e)
    {
        for (int i = 0; i < 3; i++)
        {
            System.Web.UI.StaticPartialCachingControl.BuildCachedControl(PhControls, String.Format("Test{0}", i), String.Format("1234567{0}", i), 180, null, null, null, null, new System.Web.UI.BuildMethod(GetBuilderDelegate(i)), null);
        }
    }

    public Func<Control> GetBuilderDelegate(int number)
    {
        return delegate()
        {
            var control = (UserControls.Test)LoadControl("~/UserControls/Test.ascx");
            control.Number = number;
            return control;
        };
    }

Это аккуратно заботится о разной продолжительности кэширования и в коде. Убедитесь, что вы удалили директиву OutputCache из разметки в ascx, хотя, когда вы делаете это. В противном случае LoadControl получает вам еще один PartialCachingControl, и приведение завершится неудачей.

...