带有缓存的 ASP.Net MVC 数据库驱动菜单
-
21-09-2019 - |
题
我正在尝试为我的网站创建一个菜单。它需要满足以下要求
- 它必须是数据库驱动的,从数据库中提取数据来构建菜单结构
- 从数据库中提取的数据需要缓存 - 我不想为每个页面请求访问数据库
目前,我正在运行一个简单的示例,但我不知道如何集成缓存。我想我可能必须重新设计整个方法。这里是:
我有一个 产品菜单属性, ,它从数据库中提取数据,并将其存储在 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
}
在我的 站点管理员 我从以下位置提取数据 查看数据 并用它来渲染我的菜单。这是我的无序菜单列表中的一个小片段,它使用 CSS 进行样式设置。这是代码:
<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>
然后我用以下内容装饰每个控制器 [产品菜单] 属性如下:
[ProductMenu]
public class HomeController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
现在,每当我的控制器上执行任何操作时, 动作执行时 方法中的 产品菜单属性 将调用类,这将设置 ViewData,最终将在我的 站点大师 从数据库构建我的菜单,此时我调用任何操作。
现在的问题是——如何在这种情况下添加缓存?我不知道从哪里开始,并且感觉我的解决方案不可缓存。
解决方案
我认为我真正想要的是使用 Html.RenderAction() 来自 MVC Futures 项目的辅助扩展。
这个想法是使用上面的方法来调用控制器上的操作,该操作将通过从数据库中提取数据来生成 HTML 菜单结构。然后,我还使用简单的输出缓存将数据缓存几分钟。
这是迄今为止我发现的实现我想要的目标的最简单的方法。
编辑: Phil Haack 最近在博客中谈到了这一点 - Html.RenderAction 和 Html.Action. 。一篇很棒的博客文章涵盖了我所有的具体需求,并对所有问题进行了解释。
为了使缓存正常工作,我需要将我的 Html.RenderAction()
在 a 内调用 查看用户控件 OutputCaching 指令设置如下:
<@ OutputCache Duration="100" VaryByParam="None" %>
然后我用上面的方法调用 Html.RenderPartial()
, ,瞧,一切正常!
不隶属于 StackOverflow