Excluindo controles de usuário do OutputCache em um site Sitefinity

Eu tenho um site ASP.NET construído no Sitefinity CMS. A grande maioria do site é construída usando controles de usuário de formulários da web personalizados. Sitefinity é uma boa plataforma para gerenciar conteúdo e todo esse jazz, mas se você não estiver usando sua funcionalidade outputCache (que eu acredito que seja apenas a funcionalidade outputCache do ASP.NET) seu desempenho vai explodir.

Você não pode facilmente ligar / desligar o cache para controles de usuários individuais em uma página. Tentei o atributo @outputCache na página ascx, definindo o atributo partialCaching na classe no code behind, bem como definindo programaticamente o controle partialCache conforme explicado aqui ( http://msdn.microsoft.com/en-us/library /system.web.ui.controlcachepolicy.aspx ). Nada disso funcionou. Eu poderia ter utilizado a propriedade SetVaryByCustom no cache para criar páginas personalizadas em cache para determinados valores, mas havia muitos valores potenciais. Para que serve um cache se cada usuário precisa ter sua própria versão de uma página no referido cache?

A única solução que parecia funcionar é usar o controle de substituição ASP ( http://msdn.microsoft.com/en-us/library/ms228212.aspx ). Este controle é muito simples. Você o coloca na marcação em seu ascx e quando a página é solicitada, mesmo se estiver em cache, ela executará um método estático que retorna uma string. Mas como isso pode me ajudar a substituir um controle inteiro? Seria super sujo para mim apenas colocar toda a minha marcação html em uma string e retornar isso. Felizmente, o ASP.NET permite que você renderize páginas e controles em strings.

Construa seu controle como faria normalmente. Em seguida, crie um controle de “contêiner” que renderizará o controle real. Este controle de contêiner é o que deve ser adicionado ao Sitefinity. Na marcação do controle, adicione o seguinte:

<asp:Substitution ID="Substitution1" runat="server"  
MethodName="RenderMyControl" />

Agora, em seu código atrás, adicione o seguinte método:

protected static string RenderMyControl(HttpContext context)
{
Page pageHolder = new Page();
MyControl viewControl =
(MyControl)pageHolder.LoadControl(
"/controls/MyControl.ascx");
pageHolder
.Controls.Add(viewControl);
StringWriter result = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, result, false);
return result.ToString();
}

E é isso. Agora seu controle será substituído a cada carregamento de página. Props para Jon Kragh (@jonkragh) por esta postagem do blog que me ajudou a encontrar a solução de como renderizar corretamente um controle para uma string.

http://www.jonkragh.com/index.php/rendering-an-asp-net-usercontrol-to-a-string/

Sua postagem também usa genéricos para que você possa passar qualquer controle para ser renderizado como uma string. Observe que essa solução é superior a apenas instanciar uma instância de seu controle e, em seguida, chamar o método RenderControl. Se você seguir essa rota, os eventos de ciclo de vida da página, como carregamento de página e inicialização de página , não serão disparados e você não será capaz de vincular dados a modelos em sua marcação.