我有一些想要自定义缓存的控制器操作。例如,假设我有一个
控制器操作ActionResult Index(string name) {}。我要在服务器上缓存此操作的HTML,除非URL中没有“ live = true” querystring参数。如果存在该参数,我想从服务器缓存中删除该操作结果并正常提供响应。

我们通常使用OutputCache(Location=OutputCacheLocation.Server)属性进行缓存。如果URL中存在live = true参数,是否可以通过某种方式扩展此属性并使其清除缓存?

如果无法自定义OutputCache属性以获取所需的行为,是否可以使用其他方法来完成此操作?

更新

根据詹姆斯的反馈,这里是我的代码:

public class LiveOutputCacheAttribute : OutputCacheAttribute
{
    private const string _resetParam = "live";
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var context = filterContext.HttpContext;
        AddLiveToVaryByParam();
        if (context.Request[_resetParam] == "true")
        {
            var urlToRemove = GetUrlToRemove(filterContext);
            context.Response.RemoveOutputCacheItem(urlToRemove);
            return;
        }
        base.OnActionExecuting(filterContext);
    }

    private void AddLiveToVaryByParam()
    {
        // add live reset flag when vary by param is specified
        if (VaryByParam != "*" && !VaryByParam.Contains("live"))
            VaryByParam = string.Format("{0};{1}",VaryByParam, _resetParam).TrimStart(';');
    }

    private static string GetUrlToRemove(ActionExecutingContext filterContext)
    {
        var routeValues = new RouteValueDictionary(filterContext.ActionParameters);
        var urlHelper = new UrlHelper(filterContext.RequestContext);
        string action = filterContext.ActionDescriptor.ActionName;
        string controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
        return urlHelper.Action(action, controller, routeValues);
    }
}


这是我在动作中使用它的方式:

[LiveOutputCache(Location = OutputCacheLocation.Server, Duration = 60 * 60, VaryByParam = "name")]
public ActionResult Index(string name)
{
    ViewData.Model = name + "-----" +  DateTime.Now.Ticks.ToString();
    return View();
}


问题是,当我使用live = true参数时,它仍然没有从缓存中删除原始请求。我在这里做错什么了吗?

最佳答案

您可以使用VaryByParam属性来检查live选项是否为真,例如

public class LiveOutputCacheAttribute : OutputCacheAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (VaryByParam == "true")
        {
            // clear cache
            return;
        }

        base.OnActionExecuting(filterContext);
    }
}

...

[LiveOutputCache(Location=OutputCacheLocation.Server, VaryByParam="live")]
public ActionResult Index(string name)
{
    ...
}


有关其清除部分,请参见How to programmatically clear outputcache for controller action method

07-24 09:44
查看更多