IIS 8 の Web サイトで実行されている ASP.NET MVC 5 WEB アプリケーションがあり、DB から読み取ってセッション変数に保存するユーザー設定によって実行時にプログラムで言語を変更する必要があり、この値は実行時に変更される可能性があります。ドロップダウン付き。
問題は、CurrentCulture が変更されているにもかかわらず、言語リソースが変更されないことがあり、さらに悪いことに、アプリケーション レベルでフリーズして、他のすべてのユーザー セッションもその言語にフリーズし、すべてのアプリケーション セッションで同じ言語のみが表示されることです。好みに関係なくスタックするか、実行時に言語を変更しようとしても、正常に動作しているときに CurrentThread.CurrentCulture が強制的に変更されます。
ビューで非表示のテキストを使用して、CurrentThread.CurrentCulture が何であったかを追跡し、期待どおりに変化しているため、問題は別の場所にあるはずです。
これは、CurrentCulture の検査に使用するカミソリ ブロックです。
<div style="display:none; visibility: hidden;">Thread
@System.Threading.Thread.CurrentThread.CurrentCulture</div>
また、実行時に言語または resx がアプリケーション レベルでフリーズ/スタックしている場合、値は実際には正しく選択されていますが、ビューに表示されている言語と一致せず、たとえば変更を加えるまで正常に動作しません。 web.config またはアプリケーションを再起動すると、しばらくは正常に動作しますが、あまり長くは続きません。
<div style="display:none; visibility: hidden;">Thread en-US</div>
問題は、これがすべてのユーザー セッションのアプリケーション レベルで発生し、アプリケーションが正常に動作しているときに CurrentCulture が実際に期待どおりに変化し、再起動するたびにこれが発生しないことです。現在のすべてのセッション、さらには新しいセッションの言語。
カミソリ ビュー、アクション フィルター、およびベース コントローラーにもカルチャ ロジックの変更を配置しようとしましたが、問題は解決しませんでした。以前は、すべてのコントローラーが継承したベース コントローラーと、変更する Global.asax.cs のロジックがありました。そして文化を決定します。
私の現在のアプローチは、ベースコントローラーを削除し、Global.asax.cs Application_AcquireRequestState (私も Application_BeginRequest を使用してみましたが、どういうわけかライフサイクルが早すぎます) とアクションフィルターの両方で使用することでした。
これは Global.asax.cs にあります
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (Context.Session != null && Context.Session["CultureName"] != null)
{
string cultureName = Context.Session["CultureName"].ToString();
CultureInfo cultureInfo = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
}
そして、このような私のアクションフィルター
public class CultureActionAttribute : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
string cultureName = null;
string tenant = filterContext.RouteData.Values["Tenant"] as string;
if (!String.IsNullOrWhiteSpace(tenant))
{
TenantService tenantService = new TenantService(tenant);
cultureName = CultureHelper.GetImplementedCulture(tenantService.Tenant.LanguageCulture);
tenantService.Unit.Dispose();
}
//Logic to override cultureName value by getting the user preference language
CultureInfo cultureInfo = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
}
そして、それを FilterConfig に追加しました
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new CultureActionAttribute());
//
}
ユーザーがカルチャを変更したときに ClearCachedData を使用しようとさえしました。
Thread.CurrentThread.CurrentCulture.ClearCachedData();
これはキャッシングまたはプールのリサイクルに関連している可能性があると思いますが、次に何を試すべきかわかりません。
web.config でグローバリゼーション タグを使用していません。
CurrentThread.CurrentCulture のビューでトレースされた値は常に正しいですが、問題はリソースの使用によるフリーズです。
リソースは、それらを別の専用の標準フォルダーに配置し、PublicResXFileCodeGenerator を使用してそれらを公開してコンパイルし、コントローラー、ビューなどにアクセスできるようにするという慣行と一致しています。
リソース フォルダー
誰かが私に別の選択肢を提供してくれませんか?