Меню ASP.Net MVC, управляемое базой данных, с кэшированием
-
21-09-2019 - |
Вопрос
Я пытаюсь создать меню для своего сайта.Он должен отвечать следующим требованиям
- он должен управляться базой данных и извлекать данные из БД для построения структуры меню.
- данные, извлекаемые из БД, необходимо кэшировать - я не хочу обращаться к БД для каждого запроса страницы
На данный момент у меня работает упрощенный пример, но я не знаю, как интегрировать кеширование.Я думаю, мне, возможно, придется полностью переработать весь способ, которым я это делаю.Вот:
у меня есть ProductMenuAttribute, который извлекает данные из БД и сохраняет их в 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();
}
}
Теперь всякий раз, когда выполняется какое-либо действие на моем контроллере, OnActionExecuted метод в ProductMenuAttribute будет вызван класс, который установит ViewData, который в конечном итоге будет использоваться в моем Сайт.Мастер для построения своего меню из БД, при котором я вызываю любое из действий.
Проблема теперь в том, как мне добавить кеширование в этот сценарий??Я понятия не имею, с чего начать, и чувствую, что имеющееся у меня решение не кэшируется.
Решение
Я думаю, что я действительно ищу, чтобы использовать HTML.RenderAction() вспомогательное расширение из проекта MVC Futures.
Идея состоит в том, чтобы использовать вышеизложенное для вызова действия на контроллере, который будет генерировать структуру меню HTML, извлекая данные из БД.Затем я также использую простое кэширование вывода для кэширования данных на несколько минут.
Это самый простой подход, который я нашел до сих пор, чтобы достичь того, чего я хочу.
РЕДАКТИРОВАТЬ: Фил Хаак недавно написал об этом в блоге: Html.RenderAction и Html.Action.Отличный пост в блоге, охватывающий все мои потребности, с объяснением всех проблем.
Чтобы кэширование работало правильно, мне нужно будет поместить Html.RenderAction()
позвонить внутри ViewUserControl с директивой OutputCaching, установленной следующим образом:
<@ OutputCache Duration="100" VaryByParam="None" %>
Затем я вызываю вышеуказанное с помощью Html.RenderPartial()
, и вуаля, все работает!
Другие советы
Вы можете изменить свой репозиторий, чтобы он поддерживал кэш:Посмотрите эти два вопроса:кэшированный репозиторий и HTTP-кеш.
Я сделал это с помощью блока кэширования корпоративной библиотеки.Вы проверяете наличие кешированных данных, если кешированных данных нет, вы создаете html-строку из данных в вашей базе данных и помещаете ее в кеш, чтобы позже при поиске кешированных данных вы могли просто вывести простую строку: D
Просто отметим, что код для этого находился в статическом классе.Я опубликую пример, но я переписываю это приложение в MVC2 с нуля, поэтому у меня нет кода вручную.