3

MVC アプリケーションのローカライズに夢中になっています。

私の最近の質問の後、私はこのアプローチに従いました:

  1. 言語は Session["lang"] に格納されます
  2. 各コントローラーは、OnActionExecuting をオーバーライドする独自の BaseController から継承し、このメソッドでセッションを読み取り、CurrentCulture と CurrentUICulture を設定します。

これは、データ注釈レイヤーが来るまでうまく機能します。アクション自体が実行される前に呼び出されるように見えるため、常にデフォルト言語でエラーメッセージが表示されます!

フィールド宣言は次のようになります。

[Required(ErrorMessageResourceName = "validazioneRichiesto", ErrorMessageResourceType = typeof(Resources.Resources))]
public string nome { get; set; }

それで、私が電話をかけることができる合理的な場所はありますか?

Controller コンストラクターで Data Annotation Model Binder を初期化します。

public CardController() : base() {
    ModelBinders.Binders.DefaultBinder =
    new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
}

したがって、Session はコントローラーのコンストラクターで常に null であり、データ注釈がフィールドを検証した後にアクション オーバーライドが呼び出されるため、CurrentCulture と CurrentUICulture をどこで設定してローカライズされたエラーを取得できますか?

CurrentCulture と CurrentUiCulture を Application_* (例: Application_AcquireRequestState または Application_PreRequestHandlerExecute) に入れてみましたが、効果がないようです...

4

4 に答える 4

2

カルチャはグローバル ユーザー設定であるため、Application_BeginRequest メソッドの global.asax.cs ファイルで使用しています。

それは私のために(Cookieを使用して)機能しますが、セッションもそこで利用できます。

編集:

/by ブロック・アレン: http://www.velocityreviews.com/forums/t282576-aspnet-20-session-availability-in-globalasax.html/

セッションは PreRequesthandlerExecute で利用できます。

問題は、サーバーへのすべてのリクエストに対してコードが実行され、一部のリクエスト (WebResourxe.axd のリクエストなど) がセッションを使用しないことです (ハンドラーが IRequireSessionState を実装していないため)。したがって、そのリクエストがセッションにアクセスできる場合にのみセッションにアクセスするようにコードを変更してください。

これを行うには、コードを変更します。

protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
    if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
        SetCulture();    
}

とにかく、mvcで動作するかどうかはわかりません

于 2009-10-02T11:26:58.470 に答える
1

あなたの質問をもっと注意深く読んだ後、あなたの問題はリソースのコンパイル方法にあると思います。

Resource.resxプロパティをチェックインし、Build Actionそれを見つけて設定しますEmbedded Resource また、に変更Custom ToolしますPublicResXFileCodeGenerator

代替テキスト http://img208.imageshack.us/img208/2126/captuream.png

ミニソリューションをテストしましたが、完全に機能します。さらに問題がある場合は、例をお送りします。

于 2009-10-06T15:08:39.763 に答える
0

OPは、twkによって受け入れられた回答のおかげで、最終的な解決策を次のように投稿しました。

void Application_PreRequestHandlerExecute(object sender, EventArgs e) {
  if (Context.Handler is IRequiresSessionState || 
      Context.Handler is IReadOnlySessionState) {
    if (Session["lang"] == null) {
      Session["lang"] = "it";
    }

    if (Request.QueryString["lang"] == "it" || Request.QueryString["lang"] == "en") {
      Session["lang"] = Request.QueryString["lang"];
    }

    string lang1 = Session["lang"].ToString();
    string lang2 = Session["lang"].ToString().ToUpper();

    if (lang2 == "EN")
      lang2 = "GB";

    System.Threading.Thread.CurrentThread.CurrentCulture = 
        System.Globalization.CultureInfo.CreateSpecificCulture(lang1 + "-" + lang2);
    System.Threading.Thread.CurrentThread.CurrentUICulture = 
        System.Globalization.CultureInfo.CreateSpecificCulture(lang1 + "-" + lang2);
  }
}
于 2015-02-09T14:30:10.077 に答える
0

使用できるもう 1 つの方法は、URL に lang を配置することです。この利点は次のとおりです。

  • このサイトは、さまざまな言語の検索エンジンによってスパイダー化されています
  • ユーザーは、選択した言語で URL を友人に送信できます

これを行うには、Application_BeginRequestメソッドを使用しますGlobal.asax

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
    Dim lang As String
    If HttpContext.Current.Request.Path.Contains("/en/") Then
        lang = "en"
    Else
        lang = "es"
    End If
    Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang)
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang)
End Sub

実装方法の詳細については、この質問を参照してください

于 2009-10-02T21:53:06.803 に答える