4

モデルのエラー メッセージをスペイン語で表示したいのですが、それらの文字列をリソース ファイルに定義しました。カミソリ構文を使用してページ上の他の文字列に対して同じことを行いましたが、ViewModel アノテーションからのものは選択されていません。

実際にはデフォルト値の英語を選択しています。だから私の推測では、言語/文化が検出されなかった可能性がありますが、ページ上の他の文字列はスペイン語で表示されます

//Spanish: El campo {0} se requiere
//English: The {0} field is required  <--- this comes out always irrespective of set language

[Required(ErrorMessageResourceName = "ErrorMessage_Required", 
     ErrorMessageResourceType = typeof(GlobalResources.Resources))]
[Display(Name = "CardNumber", ResourceType = typeof(GlobalResources.Resources) )]
public string CardNumber { get; set; }

コントローラーで言語を設定します

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    base.OnActionExecuting(filterContext);

    HttpCookie cookie = Request.Cookies["lang"];

    string lang = cookie != null ? cookie.Value : "en-US";
    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
}

カルチャ設定を ViewModel に拡張するにはどうすればよいですか?

更新 同様の投稿: MVC3 グローバリゼーション: モデル バインディングの前にグローバル フィルターが必要

更新 ブラウザの設定で優先言語を変更すると、機能しました。これは、モデル アトリビュートが の影響を受けないこの設定を使用していることを意味しますSystem.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);これを実現する方法はありますか?- まだ探している....

更新:コードを移動するApplication_AcquireRequestStateと解決するようです。

protected void Application_AcquireRequestState()
{
    HttpCookie cookie = Request.Cookies["lang"];

    string lang = cookie != null ? cookie.Value : "en-US";
    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
}

私が得た説明は、この質問に投稿されたリンクにもありますが、メソッドが呼び出される前にバインディングが既に発生していたため、モデルがコントローラーのオーバーライドされたメソッドで設定されているカルチャを利用するには遅すぎたということです。このリンクは役に立ちました

4

2 に答える 2

3

以下のクラスを使用してみてください

public sealed class LanguageManager
{
    /// <summary>
    /// Default CultureInfo
    /// </summary>
    public static readonly CultureInfo DefaultCulture = new CultureInfo("en-US");

    /// <summary>
    /// Available CultureInfo that according resources can be found
    /// </summary>
    public static readonly CultureInfo[] AvailableCultures;

    static LanguageManager()
    {
        List<string> availableResources = new List<string>();
        string resourcespath = Path.Combine(System.Web.HttpRuntime.AppDomainAppPath, "App_GlobalResources");
        DirectoryInfo dirInfo = new DirectoryInfo(resourcespath);
        foreach (FileInfo fi in dirInfo.GetFiles("*.*.resx", SearchOption.AllDirectories))
        {
            //Take the cultureName from resx filename, will be smt like en-US
            string cultureName = Path.GetFileNameWithoutExtension(fi.Name); //get rid of .resx
            if (cultureName.LastIndexOf(".") == cultureName.Length - 1)
                continue; //doesnt accept format FileName..resx
            cultureName = cultureName.Substring(cultureName.LastIndexOf(".") + 1);
            availableResources.Add(cultureName);
        }

        List<CultureInfo> result = new List<CultureInfo>();
        foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
        {
            //If language file can be found
            if (availableResources.Contains(culture.ToString()))
            {
                result.Add(culture);
            }
        }

        AvailableCultures = result.ToArray();

        CurrentCulture = DefaultCulture;
        if (!result.Contains(DefaultCulture) && result.Count > 0)
        {
            CurrentCulture = result[0];
        }
    }

    /// <summary>
    /// Current selected culture
    /// </summary>
    public static CultureInfo CurrentCulture
    {
        get { return Thread.CurrentThread.CurrentCulture; }
        set
        {
            Thread.CurrentThread.CurrentUICulture = value;
            Thread.CurrentThread.CurrentCulture = value;
        }
    }
}

最後に以下のようにカルチャを設定します。

LanguageManager.CurrentCulture = new CultureInfo("Your culture");

そして今、文化をオーバーライドします

于 2013-04-24T19:33:21.687 に答える
1

との両方 CurrentCultureを必ず設定してくださいCurrentUICultureCurrentCultureリソースファイルが実際に見ているものだと思います:

 //I've taken off System.Threading, add a using to it (aids readability)

 Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
 Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(lang);
于 2013-04-24T19:28:24.707 に答える