首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果param是一个列表,VaryByParam就会失败

如果param是一个列表,VaryByParam就会失败
EN

Stack Overflow用户
提问于 2014-07-21 08:29:08
回答 1查看 912关注 0票数 4

我在MVC中有了这个动作

代码语言:javascript
复制
[OutputCache(Duration = 1200, VaryByParam = "*")]
public ActionResult FilterArea( string listType, List<int> designersID, int currPage = 1 )
{
   // Code removed
}

,它无法用url显示正确的HTML,如

  • http://example.com/en-US/women/clothing?designersID=158
  • http://example.com/en-US/women/clothing?designersID=158&designersID=13

这是OutputCache在.NET中的一个已知错误,因为它不能用列表参数识别VaryByParam,还是我遗漏了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-09 19:07:16

我在MVC3中也有同样的问题,我相信在MVC5中情况仍然是一样的。

这是我的设计。

请求

POST,Content:application/json,传入一个字符串数组作为参数

代码语言:javascript
复制
{ "options": ["option1", "option2"] }

控制器方法

代码语言:javascript
复制
[OutputCache(Duration = 3600, Location = OutputCacheLocation.Any, VaryByParam = "options")]
public ActionResult GetOptionValues(List<string> options)

我在OutputCache中尝试了所有可能的选择,但对我来说并不是缓存。绑定对于实际的方法工作很好。我最大的怀疑是OutputCache没有创建唯一的缓存密钥,所以我甚至从System.Web.MVC.OutputCache中提取了它的代码来验证。我已经验证过,即使在传入List<string>时,它也正确地构建了唯一的密钥。其他的东西在那里是有问题的,但不值得花费更多的精力。

代码语言:javascript
复制
OutputCacheAttribute.GetUniqueIdFromActionParameters(filterContext,
                OutputCacheAttribute.SplitVaryByParam(this.VaryByParam);

解决办法

最后,我按照另一个SO post创建了自己的OutputCache属性。使用起来容易得多,我可以去享受这一天剩下的时光。

控制器方法

代码语言:javascript
复制
[MyOutputCache(Duration=3600)]
public ActionResult GetOptionValues(Options options)

自定义请求类

我继承了List<string>,所以我可以调用MyOutputcache类中的overriden .ToString()方法,为我提供一个唯一的缓存键字符串。只有这种办法才能为其他人解决类似的问题,但对我却没有解决。

代码语言:javascript
复制
[DataContract(Name = "Options", Namespace = "")]
public class Options: List<string>
{
    public override string ToString()
    {
        var optionsString= new StringBuilder();
        foreach (var option in this)
        {
            optionsString.Append(option);
        }
        return optionsString.ToString();
    }
}

自定义OutputCache类

代码语言:javascript
复制
public class MyOutputCache : ActionFilterAttribute
{
    private string _cachedKey;

    public int Duration { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.Url != null)
        {
            var path = filterContext.HttpContext.Request.Url.PathAndQuery;
            var attributeNames = filterContext.ActionParameters["Options"] as AttributeNames;
            if (attributeNames != null) _cachedKey = "MYOUTPUTCACHE:" + path + attributeNames;
        }
        if (filterContext.HttpContext.Cache[_cachedKey] != null)
        {
            filterContext.Result = (ActionResult) filterContext.HttpContext.Cache[_cachedKey];
        }
        else
        {
            base.OnActionExecuting(filterContext);
        }
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Cache.Add(_cachedKey, filterContext.Result, null,
            DateTime.Now.AddSeconds(Duration), System.Web.Caching.Cache.NoSlidingExpiration,
            System.Web.Caching.CacheItemPriority.Default, null);
        base.OnActionExecuted(filterContext);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24860685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档