ResouceManager有时会错误地加载ASP.Net MVC资源文件

Ste*_*evo 28 c# asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

概观

我们有一个跨国网站,为其服务的各个国家/地区提供本地化内容.使用标准.Net资源文件实现此本地化.

当我们的Web应用程序在生产环境中启动或回收负载时,有时会显示特定国家/地区的错误资源.例如,英国网站可能会显示法语内容.

这将继续发生,直到重新启动应用程序.

详情

生产环境是Windows Server 2012上的IIS 8.该应用程序在ASP.Net MVC 4中实现.

应用程序决定传入URL所服务的区域设置.所以www.mysite.com将是英国英语www.mysite.fr将是法语等.

我们有一个IHttpModule的实现,它通过Web.config注册.在模块的Init方法中,它将一个处理程序附加到BeginRequest事件.在此方法中,将检查传入的URL,并将线程的CurrentUICulture设置为适当的值.en-GB代表www.mysite.com,fr-FR代表www.mysite.fr等.

该系统在大多数情况下运行良好.但是,有时当应用程序在接收请求时启动时,它将始终为某些资源文件提供错误的内容.

它将继续执行此操作,直到重新启动应用程序.它可能会再次重新启动提供错误的内容.我们必须继续重新启动,直到它提供正确的内容,此时它将保持稳定.

分析

通过在启动期间向应用程序发送请求(使用Fiddler),我们已经能够在开发PC上本地重现这一点.该网站显示了英国版网站上某些资源文件的德语内容.

检查过明显的罪魁祸首在我们的代码(该的CurrentUICulture是由HTTP模块正确设置并保持整个请求的处理是正确的),我们开始来看看资源管理器.

在应用程序以不正确的状态启动时,我们检查了ResourceManager类上_resourceSets属性的内容.这是一个以ISO文化代码为主的字典.检查en-GB的内容,我们发现它确实包含来自德语版资源文件的资源字符串.

似乎有时,当站点在接收请求时启动时,ResourceManager类正在为文化加载错误的资源文件,或者它在其Dictionary中错误地对文件进行了分类.

有没有其他人经历过这种行为,是否有人知道任何变通办法?

谢谢.

Bru*_*Dev 5

这听起来像是你的处理程序中存在线程安全问题.当您修改线程当前区域性时,您正在为可能正在处理多个请求的当前线程修改它.生成响应时,另一个请求可能会改变当前的线程语言,使所有响应都使用相同的语言.

我可以从一开始就提出一些建议:

  1. 确保您的处理程序不可重用.我假设你已经实现了IHttpHandler,为IsReusable属性返回false,因为多个线程应该同时命中它,并且每个请求都会创建一个新实例.
  2. 不要使用处理程序......处理程序不是这样的理想解决方案,设置线程文化的首选位置是Application_AcquireRequestState,它将针对每个请求正确触发而不重叠.
  3. 请改用路由处理程序:http://adamyan.blogspot.com/2010/07/addition-to-aspnet-mvc-localization.html

如果没有看到处理程序,你会谈到剩下的只能是为什么响应分享线程文化的猜测.问题可能很容易出现在您正在使用的字典中,这本身就不是线程安全的.

  • "在负载下"是可疑的,因为当多个请求正在改变当前的UI线程文化时,资源管理器可以正确地构建它的内容.您是否尝试在其中一个HttpContext事件中执行此操作?在处理任何请求之前,您可能最好在Application_Start上预热资源管理器,因此在可以充满请求之前正确设置它. (2认同)