Кэширование звонка в Html.Action - PullRequest
1 голос
/ 25 ноября 2010

Я пытаюсь кэшировать вызов метода действия в ASP.NET MVC3 RC1.

Кэширование работает, но изменение по параметру, похоже, не увеличивается. Могу ли я сделать так, чтобы 3 вызова HotOffers возвращали разные результаты в зависимости от productID?

Вывод прямо сейчас

Горячие предложения 4

Горячие предложения 4

Горячие предложения 4

Я хочу, чтобы вывод был

Горячие предложения 4

Горячие предложения 6

Горячие предложения 8

Действие

[OutputCache(Duration = 100, VaryByParam = "productId")]
public PartialViewResult HotOffers(int productId)
{
    ProductModel model = new ProductModel { ProductID = productId };
    model.Name = "Meatball";

    return PartialView(model);
}

Страница (Index.cshtml)

@{
    View.Title = "Home Page";
}
<p>
<div>
    @Html.Action("HotOffers", new { productid=4})
</div>
<div>
 @Html.Action("HotOffers", new { productid=6})
</div>
 <div>
 @Html.Action("HotOffers", new { productid = 8 })
</div>
</p>

Частично (HotOffers.cshtml)

Hot offers
@Model.ProductID

1 Ответ

1 голос
/ 25 ноября 2010

Система кэширования, используемая asp.net, существует вне MVC и поэтому применяется только к URL-адресам, а затем VaryByParam применяется только к параметрам QueryString.

Я опубликовал некоторый код Поведение OutputCache в ASP.NET MVC 3 , и это должно помочь вам начать кэширование действий на основе параметров. В этом конкретном примере я добавил параметр «игнорировать», который фактически игнорирует одно из полей маршрута, но вы можете просто удалить его, и все будет в порядке.

Полагаю, я могу опубликовать это здесь без игнорирования

public class ActionOutputCacheAttribute : ActionFilterAttribute {
    public ActionOutputCacheAttribute(int cacheDuration) {
        this.cacheDuration = cacheDuration;
    }

    private int cacheDuration;
    private string cacheKey;

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        string url = filterContext.HttpContext.Request.Url.PathAndQuery;
        this.cacheKey = ComputeCacheKey(filterContext);

        if (filterContext.HttpContext.Cache[this.cacheKey] != null) {
            //Setting the result prevents the action itself to be executed
            filterContext.Result =
            (ActionResult)filterContext.HttpContext.Cache[this.cacheKey];
        }

        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        //Add the ActionResult to cache 
        filterContext.HttpContext.Cache.Add(this.cacheKey, filterContext.Result,null, DateTime.Now.AddSeconds(cacheDuration),
          System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);

        //Add a value in order to know the last time it was cached.
        filterContext.Controller.ViewData["CachedStamp"] = DateTime.Now;

        base.OnActionExecuted(filterContext);
    }

    private string ComputeCacheKey(ActionExecutingContext filterContext) {
        var keyBuilder = new StringBuilder();
        keyBuilder.Append(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
        keyBuilder.Append(filterContext.ActionDescriptor.ActionName);

        foreach (var pair in filterContext.RouteData.Values) {
            if(pair.Value != null)
                keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
        }
        return keyBuilder.ToString();
    }
}

Код выше был модификацией http://blog.stevensanderson.com/2008/10/15/partial-output-caching-in-aspnet-mvc/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...