OutputCache with VaryByCustom not working

跟風遠走 提交于 2021-01-27 06:09:29

问题


I'm trying to implement caching in ASP.NET MVC 4 using the OutputCache attribute.

Here is my controller action:

[HttpGet]
[OutputCache(Duration = CACHE_DURATION, VaryByCustom = "$LanguageCode;myParam", Location = OutputCacheLocation.Server)]
public JsonResult MyAction(string myParam)
{
    // this is called also if should be cached!
}

And here is the GetVaryByCustomString in the Global.asax:

public override string GetVaryByCustomString(HttpContext context, string arg)
{
    var pars = arg.Split(';');
    if (pars.Length == 0) return string.Empty;

    var res = new System.Text.StringBuilder();
    foreach (var s in pars)
    {
        switch (s)
        {
            case "$LanguageCode":
                var culture = CultureManager.GetCurrentCulture();
                res.Append(culture.Name);
                break;
            default:
                var par = context.Request[s];
                if (par != null)
                    res.AppendFormat(par);
                break;
        }
    }
    return base.GetVaryByCustomString(context, res.ToString());
}

This method is always called and returns the right value (e.g. "it123").

If I call the action with the only myParam parameter, the cache works correctly.

http://localhost:1592/MyController/MyAction?myParam=123 // called multiple times always read from cache

The problem is that when I call the action with another parameter, not included in the VaryByCustom string, the controller action is called anyway, also if is should be cached and the GetVaryByCustomString returns the same result.

http://localhost:1592/MyController/MyAction?myParam=123&dummy=asdf // called multiple times with different 'dummy' values always calls the action

Any idea?


回答1:


First you have to change your [OutputCache] to include VaryByParam="":

[OutputCache(Duration = CACHE_DURATION, VaryByCustom = "$LanguageCode;myParam", VaryByParam = "", Location = OutputCacheLocation.Server)]

Becuase by default its value is "*" (All).

Then in your GetVaryByCustomString() method, try to return your generated string instead of calling the base method:

return res.ToString();

Here's the source code of the base.GetVaryByCustomString() method:

public virtual string GetVaryByCustomString(HttpContext context, string custom) {

        if (StringUtil.EqualsIgnoreCase(custom, "browser")) {
            return context.Request.Browser.Type;
        }

        return null;
    }

As you can see, it doesn't do what you think it does, it only compares the Browser type with the string you provided and if there's no match it returns null, not the string you provided.

(I suspect the [OutputCache] change alone will suffice, but try changing the method as well)



来源:https://stackoverflow.com/questions/22992661/outputcache-with-varybycustom-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!