Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 视图上的Resx缓存问题_C#_Asp.net_Asp.net Mvc_Razor_Resx - Fatal编程技术网

C# 视图上的Resx缓存问题

C# 视图上的Resx缓存问题,c#,asp.net,asp.net-mvc,razor,resx,C#,Asp.net,Asp.net Mvc,Razor,Resx,这是一个.NET4.5项目,在我来这里之前很久就已经建立了,所以没有太多的细节来解释为什么要这样做 我们有一个web应用程序,其中每种语言都有自己的resx文件。 在每次页面加载时,都会按照通常的方式从resx文件加载值 string strLangResourceValue = (string)HttpContext.GetGlobalResourceObject(lang, strLangResourceKey); 这个很好用。值得一提的是,这一行代码位于一个单独的项目中,因此它可以与解决

这是一个.NET4.5项目,在我来这里之前很久就已经建立了,所以没有太多的细节来解释为什么要这样做

我们有一个web应用程序,其中每种语言都有自己的resx文件。 在每次页面加载时,都会按照通常的方式从resx文件加载值

string strLangResourceValue = (string)HttpContext.GetGlobalResourceObject(lang, strLangResourceKey);
这个很好用。值得一提的是,这一行代码位于一个单独的项目中,因此它可以与解决方案下的多个其他项目共享

在视图(Razor)中,我们执行
@Application.GetLangResource(“Some_Key”)以检索我们需要的值。该语言取自HttpContext中存储的会话模型

当我们更改语言时,问题就出现了,除了我们更改语言的“用户设置”页面外,该页面上的每个部分视图都会相应地进行翻译。奇怪的是,我们有两个视图,一个只读页面只显示数据,另一个包含修改值的实际形式,并且没有一个被翻译

已知问题包括:

  • 我现在无法在web应用程序中设置CultureInfo,我需要使用会话模型来获取此信息,并使用上面的代码行来获取数据
  • 强制刷新浏览器、清除Cookie和缓存并不能解决此问题
  • 只有重新启动IIS服务器才能修复此问题(重新编译resx文件)
我知道resx文件是在运行时编译的,是静态的。在应用程序运行期间,它们不会在代码中更改,只会更改用户会话。上面的列表试图找出问题的根源,但每次有人更改语言时都重新启动应用程序不是一个选项(正如您可能猜到的)

有没有一个明显的解决办法,我没有没有resx错误,只有两个特定页面上的IIS缓存(或者至少看起来是这样)。它们的构造方式与其他所有的一样,只是没有转换语言。这适用于所有更改语言的用户

我已经尝试使用下面的代码行手动清除缓存,但没有这样做,作业问题仍然存在

Resources.AppSettings.ResourceManager.ReleaseAllResources();
Resources.English.ResourceManager.ReleaseAllResources();
Resources.Dutch.ResourceManager.ReleaseAllResources();
HttpResponse.RemoveOutputCacheItem("/Views/User/userViewDetails.cshtml");

foreach(System.Collections.DictionaryEntry entry in HttpContext.Cache) {
    HttpContext.Cache.Remove((string) entry.Key);
}

我终于弄清了自己的问题,但我仍然不明白这是怎么回事。所以,问题在于,在第一次视图渲染时,它会从resx获取相应语言的值,但在任何后续渲染时都不会(就像它会缓存这些值以缩短对resx的访问时间一样,这非常好)

我最终实现了自己的
DataAnnotationsModelMetadataProvider
,它做得很好

因此,对于任何对我的解决方案感兴趣的人来说,它看起来大致如下:

public class LocalizedDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
{

    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
    {
        var meta = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);  //  Get metadata of the property

        string resXKey = string.Empty;
        object attribute = attributes.OfType<DisplayLabel>().FirstOrDefault();  //  Try to get the DisplayLabel annotation

        //  If DisplayLabel is found then...
        if (attribute != null)
        {
            resXKey = ((DisplayLabel)attribute).Key;    //  Grab the resx key added to the annotation
            meta.DisplayName = Application.GetLangResource(resXKey) + meta.DisplayName; //  Retrieve the language resource for the key and add back any trailing items returned by the annotation
        }

        //  DisplayLabel is not found...
        if (attribute == null)
        {
            attribute = attributes.OfType<DisplayNameLocalizedAttribute>().FirstOrDefault();    //  Try to get the DisplayNameLocalizedAttribute annotation

            //  If annotation exists then...
            if (attribute != null)
            {
                resXKey = ((DisplayNameLocalizedAttribute)attribute).Key;   //  Grab the resx key added to the annotation

                string resXValue = Application.GetLangResource(resXKey);    //  Retrieve the language resource for the key
                string finalValue = resXValue;  //  Create a new string

                if (((DisplayNameLocalizedAttribute)attribute).IsLabel) //  Check if property annotation is set to label
                {
                    finalValue = resXValue + meta.DisplayName;  //  Add back any trailing items returned by the annotation
                }


                meta.DisplayName = finalValue;  //  Set the DisplayName of the property back onto the meta
            }
        }

        return meta;
    }

} 

重要的是(如果您在global.asax中出错),您使用的是
System.Mvc
,而不是出现在
modelmataproviders
中的另一个导入,因为它不允许您分配新的提供程序。

有关不涉及会话或缓存的替代方法,请参阅。@NightOwl888,我尝试了另一种解决办法。在进一步调试之后,在加载第一页后,似乎不再从resx获取值。我目前正在测试另一种方法,到目前为止似乎还有效。如果一切顺利,我将在这里发布我的解决方案。再次感谢。
LocalizedDataAnnotationsModelMetadataProvider loca = new LocalizedDataAnnotationsModelMetadataProvider();

ModelMetadataProviders.Current = loca;