5

プロジェクトを衛星アセンブリを使用するように変換しています。新しいクラスライブラリ(「リソース」という名前)を作成しました。デフォルトのリソースはすべてルートレベルにあります*.resx。次に、カルチャごとにフォルダがあります。

「en/」と *.en.resx

en-GB/と*.en-GB.resx

.resxファイルAccess Modifierを「パブリック」に変更し、これらの設定を変更しました。

BuildAction: EmbeddedResource
CopyToOutputDirectory: CopyAlways

.resxデザイナー*.Designer.csが「Resources」名前名を使用するようにしました。

クラスライブラリをASP.NETMVCアプリに追加し、global.asax.cs必要に応じてカルチャを設定しています。

System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");

Resourcesクラスライブラリのビルド後のイベントにal.exeandコマンドを追加してみました。Resgen.exe

"C:\ Program Files \ Microsoft SDKs \ Windows \ v7.1 \ Bin \ Resgen.exe" en-GB / MyResourceFile.en-GB.resx "C:\ Program Files \ Microsoft SDKs \ Windows \ v7.1 \ Bin \ al.exe "/ t:lib /embed:en-GB/MyResourceFile.en-GB.resources /culture:en-gb /out:Resources.resources.dll

MVCアプリbin/フォルダー内を見ると、3つのファイルを含む各言語のフォルダーがあります。

MyResources.en-GB.Designer.cs、MyResources.en-GB.resx、Resources.resources.dll

ルートレベルにはがResources.dllありResources.resources.dllますが、デフォルトの言語は正常に機能します。2つ目*.resources.dllは、ビルド後のイベントによるものです。

CurrentUICultureを変更しても、UI言語は変更されません。リソースをApp_GlobalResources/外部アセンブリに移動する前は、正常に機能していました(Razorの例)。

@Resources.MyResources.StringIdentifier 

.dlls.NET Reflectorを使用してリソースを見ると、これらが違いです。

Satellite Resources: (Project: Resources)
Resources.en_GB.MyResources.en-GB.resources 
App_GlobalResources: (Project MVCApp)
Namespace.MVCApp.App_GlobalResources.MyResources.en-GB.resources

編集:

でCurrentCultureとUICultureを設定した後、実際に機能global.asax.csするを手動で取得ResourceManagerして、期待される言語で文字列を取得することをテストしました。

            System.Resources.ResourceManager gStrings =
                new System.Resources.ResourceManager("Resources.MyResources", System.Reflection.Assembly.Load("Resources")); // Resources=Project Name
            string test = gStrings.GetString("TestString"); // WORKS IN GLOBAL.ASAX.CS!!!

MVCコントローラーで同じテストを試しましたが、機能しません。したがって、ResourceManagerを取得できるのはGlobal.asax.csだけです。

奇妙なことに、かみそりのUIレベルで同じテストを行うと、デフォルトのカルチャテキストしか返されません。cultureInfoは正しいですが、ResourceManagerはASP.NET MVCRazorUIのデフォルト言語のみを返します。(これは厳密にテスト用です)

    @{  
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentUICulture;
        System.Resources.ResourceManager gStrings =
            new System.Resources.ResourceManager("Resources.MyResource", System.Reflection.Assembly.Load("Resources"));
        string s = gStrings.GetString("Test");    // DOESN'T WORK IN UI
    }

TLDRバージョン:

リソース(.resx)からApp_GlobalResourcesからサテライトアセンブリへの変換。

手元の問題。

CurrentUICulture言語を使用してサテライトアセンブリのResourceManagerを手動で呼び出すことができ、global.asax期待どおりに機能しますが、同じテストがUI側から失敗し、MVCコントローラーで失敗します。

デフォルトの言語は正常に機能しますが、UIが言語を切り替えないのはなぜですか?

4

1 に答える 1

1

あなたが説明したように、内部化が多かれ少なかれ正しく機能するプロジェクトを最近セットアップした場合。

https://github.com/Jacco/Perpetuality

ベースとして使用するコントローラーの OnAuthorize で HTTP リクエストごとに言語を切り替えます。

using Perpetuality.Data;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;


namespace Perpetuality.Controllers
{
    public partial class BaseController : Controller
    {
        private CultureInfo GetCultureInfo(AuthorizationContext filterContext)
        {
            switch ((string)filterContext.RouteData.Values["language"])
            {
                case "nl":
                    return CultureInfo.CreateSpecificCulture("nl-NL");
                case "en":
                    return CultureInfo.CreateSpecificCulture("en-US");
                case "pt":
                    return CultureInfo.CreateSpecificCulture("pt-PT");
                case "de":
                    return CultureInfo.CreateSpecificCulture("de-DE");
                case "es":
                    return CultureInfo.CreateSpecificCulture("es-ES");
                case "fr":
                    return CultureInfo.CreateSpecificCulture("fr-FR");
                case "it":
                    return CultureInfo.CreateSpecificCulture("it-IT");
                case "jp":
                    return CultureInfo.CreateSpecificCulture("ja-JP");
                default:
                    return CultureInfo.CreateSpecificCulture("en-US");
            }
        }

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            Thread.CurrentThread.CurrentCulture = GetCultureInfo(filterContext);
            Thread.CurrentThread.CurrentUICulture = GetCultureInfo(filterContext);

            base.OnAuthorization(filterContext);
        }
    }
}

私のプロジェクトでは、RESX ファイルはあなたのものとは異なる方法で指定されています。

BuildAction: EmbeddedResource
CopyToOutputDirectory: DoNotCopy

私の vies では、次のように文字列にアクセスします。

@Resources.Home.Index.FacebookButtonCaption

ビルド後またはビルド前に何もセットアップしませんでした。

私のプロジェクトでは、言語は常に URL にあります。これは、適切な言語が最初に選択されていない場合、ユーザーが言語を切り替えることができるというものでした。

于 2013-05-13T06:13:14.787 に答える