防止在MVC

时间:2016-09-20 18:10:46

标签: asp.net-mvc caching

我有一个自定义显示名称属性,可根据用户的语言首选项翻译字段名称。不幸的是,无论后续用户的语言偏好如何,都会为每个后续请求缓存第一个用户的语言首选项。结果是页面内容,标题和菜单项以适当的语言显示,但只有标记的字段显示的语言不正确。

以下是我正在使用的视图模型的一部分:

public class RegisterViewModel
{
    [CustomEmailAddress]
    [CustomDisplayName("lbl_email")]
    public string Email { get; set; }    
    [CustomRequired]
    [CustomDisplayName("lbl_fn")]
    [StringLength(255)]
    public string FirstName { get; set; }    
    ...
}

以下是“自定义显示名称”属性:

public class CustomDisplayNameAttribute : DisplayNameAttribute
    {
        public CustomDisplayNameAttribute(string value = "")
            : base(GetMessageFromResource(value))
        {
        }

        private static string GetMessageFromResource(string value)
        {
            string CurrentUser;
            try
            {
                CurrentUser = HttpContext.Current.User.Identity.Name;
            }
            catch
            {
                CurrentUser = "";
            }
            string lang = ModelInit.repo.LangCode(CurrentUser);
            string ItemLegend = ModelInit.repo.TranslateItem(value, lang);
            return ItemLegend;
        }
    }

在调试问题时,我发现即使在用户注销并且新用户登录后,MVC也不打算在后续请求中点击“CustomDisplayNameAttribute”类。所以我也尝试用以下方式装饰自定义显示属性:

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]

但它也没有用。如果无法更改此行为(因为它是内置于框架中),那么有什么方法可以在用户注销时从“自定义显示名称”属性中清除缓存吗? (实际上,这将是我首选的解决方案!)现在,清除它的唯一方法是停止并重新启动程序。

1 个答案:

答案 0 :(得分:0)

简答:没有

OutputCacheAttribute用于缓存整个控制器方法的输出,但与模型属性的缓存无关。由于属性只是静态元数据,因此MVC需要使用反射来检索它,并通过缓存结果来最小化这种相对慢的操作的效果。

不幸的是,没有办法清除这个缓存,可能是因为以多线程,安全的方式这样做会需要锁定会妨碍性能。

请注意,整个MVC中都有多个缓存,包括模型元数据,视图位置和(可选)控制器输出。每个都使用单独的实现和缓存密钥策略,我在尝试在MVC上创建多租户时发现了这一点。使用MVC 6,事情变得更好(更容易)。