OutputCache与VaryByCustom无法正常工作

Fle*_*777 5 c# asp.net asp.net-mvc outputcache asp.net-mvc-4

我正在尝试使用OutputCache属性在ASP.NET MVC 4中实现缓存.

这是我的控制器动作:

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

这是Global.asax中的GetVaryByCustomString:

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());
}
Run Code Online (Sandbox Code Playgroud)

始终调用此方法并返回正确的值(例如"it123").

如果我使用唯一myParam参数调用操作,则缓存可以正常工作.

http://localhost:1592/MyController/MyAction?myParam=123 // called multiple times always read from cache
Run Code Online (Sandbox Code Playgroud)

问题是,当我用另一个参数(不包含在VaryByCustom字符串中)调用动作时,无论如何都会调用控制器动作,如果应该被高速缓存并GetVaryByCustomString返回相同的结果.

http://localhost:1592/MyController/MyAction?myParam=123&dummy=asdf // called multiple times with different 'dummy' values always calls the action
Run Code Online (Sandbox Code Playgroud)

任何的想法?

hai*_*770 9

首先,你必须改变你[OutputCache]的包括VaryByParam="":

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

因为默认情况下它的值是"*"(全部).

然后在您的GetVaryByCustomString()方法中,尝试返回生成的字符串,而不是调用基本方法:

return res.ToString();
Run Code Online (Sandbox Code Playgroud)

这是方法的源代码base.GetVaryByCustomString():

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

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

        return null;
    }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它不会按照您的想法执行,它只会将浏览器类型与您提供的字符串进行比较,如果没有匹配则返回null,而不是string您提供的.

(我怀疑[OutputCache]单独改变就足够了,但也尝试改变方法)