我有一个自定义显示名称属性,可根据用户的语言首选项翻译字段名称。不幸的是,无论后续用户的语言偏好如何,都会为每个后续请求缓存第一个用户的语言首选项。结果是页面内容,标题和菜单项以适当的语言显示,但只有标记的字段显示的语言不正确。
以下是我正在使用的视图模型的一部分:
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)]
但它也没有用。如果无法更改此行为(因为它是内置于框架中),那么有什么方法可以在用户注销时从“自定义显示名称”属性中清除缓存吗? (实际上,这将是我首选的解决方案!)现在,清除它的唯一方法是停止并重新启动程序。
答案 0 :(得分:0)
简答:没有
OutputCacheAttribute用于缓存整个控制器方法的输出,但与模型属性的缓存无关。由于属性只是静态元数据,因此MVC需要使用反射来检索它,并通过缓存结果来最小化这种相对慢的操作的效果。
不幸的是,没有办法清除这个缓存,可能是因为以多线程,安全的方式这样做会需要锁定会妨碍性能。
请注意,整个MVC中都有多个缓存,包括模型元数据,视图位置和(可选)控制器输出。每个都使用单独的实现和缓存密钥策略,我在尝试在MVC上创建多租户时发现了这一点。使用MVC 6,事情变得更好(更容易)。