Я пытаюсь создать меню для своего веб-сайта. Это должно отвечать следующим требованиям
В данный момент у меня есть упрощенное выполнение в качестве примера, но я не знаю, как интегрировать кэширование. Я думаю, что мне, возможно, придется переделать весь способ, которым я делаю это.Вот:
У меня есть ProductMenuAttribute, который вытягивает данные из DB и хранит его в 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
}
В моем Site.master я вытягиваю данные ViewData и использую его для рендеринга моего меню. Это - маленький отрывок в моем незаказанном списке меню, который разрабатывается с помощью 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] attribuate следующим образом:
[ProductMenu]
public class HomeController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
Теперь каждый раз, когда любое из действий с моим контроллером поражено, метод OnActionExecuted в классе ProductMenuAttribute назовут, который установит ViewData, который будет в конечном счете использоваться на моем Сайте. Ведущее устройство для создания моего меню от DB который время я называю любое из действий.
Проблема теперь - как я добавляю кэширование к этому сценарию?? У меня нет подсказки, где запустить, и иметь чувство решение, я имею, не является кэшируемым.
Я думаю, что на самом деле мне нужно использовать Html.RenderAction() вспомогательное расширение из проекта MVC Futures.
Идея заключается в том, чтобы использовать вышеприведенное для вызова действия на контроллере, которое сгенерирует структуру HTML-меню путем извлечения данных из БД. Затем я также использую простое Output Caching (Выходное кэширование) для кэширования данных на несколько минут...
Это самый простой подход, который я нашел до сих пор, чтобы достичь того, чего я хочу.
EDIT: Фил Хаак недавно вел блог об этом - Html.RenderAction и Html.Action. Отличный пост в блоге, охватывающий все мои точные потребности, с объяснениями всех проблем.
Чтобы кэширование работало корректно, мне нужно поместить мой вызов Html.RenderAction()
внутри ViewUserControl с директивой OutputCaching следующим образом:
<@ OutputCache Duration="100" VaryByParam="None" %>
Затем я вызываю вышеприведенный вызов с помощью Html.RenderPartial()
, и вуаля, все работает!
Вы можете модифицировать свой репозиторий, чтобы он был кэширован: См. эти два вопроса: кэшированный репозиторий и http кэш.
.