ASP.NET MVC Menu com armazenamento em cache
-
21-09-2019 - |
Pergunta
Estou tentando criar um menu para o meu site. Precisa atender aos seguintes requisitos
- Deve ser acionado por banco de dados, puxando dados do banco de dados para criar a estrutura do menu
- Os dados que estão sendo retirados do banco de dados precisam ser armazenados em cache - eu não quero acertar o banco de dados para cada solicitação de página
No momento, tenho um exemplo simplista em execução, mas não sei como integrar o cache. Eu acho que talvez precise refazer o caminho todo, faço isso. Aqui está:
eu tenho um ProductMenuattribute, que puxa os dados do banco de dados e os armazena no ViewData:
public class ProductMenuAttribute: FilterAttribute, IActionFilter
{
#region IActionFilter Members
public void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext != null)
{
var context = filterContext.Result as ViewResult;
if (context != null)
{
ProductsRepository repository = new ProductsRepository(Properties.Settings.Default.SqlConnectionString);
context.ViewData.Add("ProductsList", repository.GetAllProductRanges());
}
}
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
#endregion
}
No meu Site.master Eu puxo os dados do Ver dados e use -o para renderizar meu menu. Este é um pequeno trecho na minha lista de menus não ordenados, que é denominada com CSS. Aqui está o código:
<li>
<%= Html.ActionLink("Products", "Index", "Products")%>
<% IQueryable<ProductRange> productRanges = ViewData["ProductsList"] as IQueryable<ProductRange>; %>
<% if (productRanges != null)
{ %>
<ul>
<% foreach (ProductRange range in productRanges)
{ %>
<li><%= Html.ActionLink(range.Name, "RangeDetails", "Products", new { id = range.ID }, null)%></li>
<% } %>
</ul>
<% } %>
</li>
Eu então decoro cada controlador com o ProductMenu atribui o seguinte:
[ProductMenu]
public class HomeController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
Agora, sempre que qualquer uma das ações no meu controlador é atingida, o OnactionExecutado Método no ProductMenuattribute A classe será chamada, que definirá o ViewData, que acabará sendo usado no meu Site.master Para construir meu menu no banco de dados, que eu chamo de alguma das ações.
O problema agora é - como adiciono armazenamento em cache a esse cenário? Não tenho idéia de onde começar e tenho a sensação de que a solução que tenho não é cache.
Solução
Eu acho que o que realmente estou procurando é usar o Html.renderaction () Extensão auxiliar do projeto Futures do MVC.
A idéia é usar o acima para chamar uma ação em um controlador, que gerará a estrutura do menu HTML puxando dados do banco de dados. Também uso o cache de saída simples para armazenar em cache os dados por alguns minutos.
Esta é a abordagem mais simples que encontrei até agora para alcançar o que quero.
EDITAR: Phil Haack blogou sobre isso recentemente - Html.renderaction e html.action. Uma ótima postagem no blog, cobrindo todas as minhas necessidades exatas, com explicações de todos os problemas.
Para fazer o cache funcionar corretamente, eu precisaria colocar meu Html.RenderAction()
ligue para dentro de um ViewUserControl Com a diretiva de saída de saída, o seguinte:
<@ OutputCache Duration="100" VaryByParam="None" %>
Eu então ligo para o acima com Html.RenderPartial()
, E pronto, tudo funciona!
Outras dicas
Você pode modificar seu repositório para ter consciência de cache: veja as duas perguntas:Repositório em cache e cache http.
Eu fiz isso usando o bloco de cache da biblioteca Enterprise. Você verifica os dados em cache, se não houver dados em cache, você cria string html a partir de dados no seu banco de dados e o coloca em cache, portanto, mais tarde ao pesquisar dados em cache, você pode apenas produzir string simples: D
Só para mencionar esse código para fazer isso na classe estática. Vou postar um exemplo, mas estou reescrevendo esse aplicativo no MVC2 do zero, para não ter código manualmente.