web-dev-qa-db-ja.com

Blazor(サーバー)で現在のカルチャの日付形式を変更する方法

ASP.NET Core Blazorグローバリゼーションおよびローカリゼーション 状態:

Blazorの@bind機能は、フォーマットを実行し、ユーザーの現在のカルチャに基づいて値を表示用に解析します。
現在のカルチャーにはSystem.Globalization.CultureInfo.CurrentCulture propertyからアクセスできます。

ステートメントは真実ですが、問題は、カルチャは使用される直前に(またはおそらくDOMが更新されるたびに)設定する必要があることです。

デモでは、標準的なブレイザーカウンターアプリケーションを使用します。 Counter.razorを変更しましょう

@page "/counter"
@using System.Globalization;

<h1>Counter</h1>
<input type="text" @bind="currentDate" />

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private DateTime currentDate = DateTime.Now;
    private int currentCount = 0;

    private void IncrementCount() {
        if (currentCount < 2) Utils.SetCCDateFormat();
        currentCount++;
    }

    public class Utils {
        public static void SetCCDateFormat() {
            var cc = CultureInfo.CurrentCulture.Clone() as CultureInfo;
            cc.DateTimeFormat.ShortDatePattern = "dd-yyyy-m";
            CultureInfo.CurrentCulture = cc;
            CultureInfo.CurrentUICulture = cc;
        }
    }

} 

結果は次のとおりです。

  • ページが最初に表示されるとき、テキストボックスにはサーバーのデフォルトのカルチャでフォーマットされた日付が含まれています。
  • ボタンを最初に押したときと2回目に押したときの日付形式はdd-yyyy-m

OnAfterRenderOnInitializedの日付を変更しようとしましたが、成功しませんでした。私が見つけた唯一の使用可能な解決策は、かみそりのマークアップの懇願にフォーマットを設定することです。

@{Utils.SetCCDateFormat();}

CurrentCultureを変更してブレイザー回路で永続的になる方法はありますか?

観察された動作は正しいですか、それともバグですか?

編集

これまでに見つけたもの

文化のプロパティ(CultureInfo.CurrentCulture)をミドルウェアbeforeに設定して、ブレイザーエンドポイントが作成され、変更が回路の寿命の間持続することが可能です。 。コンポーネントのライフサイクルメソッドでCurrentCultureを変更する場合、変更は一時的です(メソッドの最後まで)。

私の問題の理解は

  • 回路が作成されると、現在のカルチャーがどこかに保存されます
  • サーバーのスレッド数は限られています
  • スレッドは必要に応じて回路に割り当てられ、現在のカルチャーは最初に保存されたものによって設定されます
  • CurrentCultureを変更することは可能ですが、これは設定のストレージに影響しないため、別のイベントメソッドが呼び出されたとき(別のスレッド)、元のカルチャが使用されます。

だから問題は次のようです:それが既に作成されているときに回路文化の設定を変更する方法?

おそらくそれは不可能であり、フルリフレッシュ(ナビゲーションでリクエストを再開)し、ミドルウェアを使用して変更されたカルチャを設定する必要があります。カルチャーストレージの存在は私の推測にすぎず、それをサポートする参照はありません。

TyethとAshiquzzamanの助けに感謝しますが、私は彼らの試みを答えとはしていません。

9
IvanH

Ashiquzzamanの回答の2番目の部分(ORの後)は、正しいパスを示しています。

組み込みのASP.Net Coreローカリゼーションミドルウェアが新しい親友になります: https://docs.Microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-3.1#localization-ミドルウェア

デフォルトで含まれているCookieRequestCultureProviderに依存することができ、ユーザーごとにログインしたユーザーのCookieを設定することで(ユーザーが保存した設定にアクセスできるため、ログイン時にお勧めします)、デフォルトのブラウザが要求する言語(または最後の手段としてのシステムデフォルト)。

リストされたRequestLocalizationProvidersの順序は投稿されたリンク上にあり、クエリ文字列がブラウザの設定を上書きできるCookieを上書きできることを示唆しています。

https://docs.Microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-3.1#cookierequestcultureprovider

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider **
  3. AcceptLanguageHeaderRequestCultureProvider

CookieRequestCultureProvider DefaultCookieNameは、ユーザーの優先するカルチャ情報を追跡するために使用されるデフォルトのCookie名を返します。デフォルトのCookie名は.AspNetCore.Cultureです。

Cookieの形式はc =%LANGCODE%| uic =%LANGCODE%です。ここで、cはカルチャ、uicはUICultureです。次に例を示します。

c=en-UK|uic=en-US

Ashiquzzamanの提案に従って、グローバリゼーションとローカリゼーションに関するブレイザーセクションを必ずお読みください: https://docs.Microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-3.1

1
Tyeth

1) ミドルウェア を使用します

例:

_    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      //your Code
        app.Use(async (context, next) =>
        {
            var culture = CultureInfo.CurrentCulture.Clone() as CultureInfo;// Set user culture here
            culture.DateTimeFormat.ShortDatePattern = "dd-yyyy-m";
            CultureInfo.CurrentCulture = culture;
            CultureInfo.CurrentUICulture = culture;

            // Call the next delegate/middleware in the pipeline
            await next();
        });
      //your Code
    }
_

2)サービス付きのカスタムミドルウェア:

サービス:

_public interface ICultureService
{
    void SetCCDateFormat();
}
public class CultureService : ICultureService
{
    public void SetCCDateFormat()
    {
        CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
        culture.DateTimeFormat.ShortDatePattern = "dd-yyyy-m";
        CultureInfo.CurrentCulture = culture;
        CultureInfo.CurrentUICulture = culture;
    }
}
_

ミドルウェア:

_public class CultureMiddleware
{
    private readonly RequestDelegate _next;

    public CultureMiddleware(RequestDelegate next)
    {
        _next = next;

    }

    public Task Invoke(HttpContext context, ICultureService culture)
    {           
        culture.SetCCDateFormat();
        return this._next(context);
    }
}
_

スタートアップ:

_    public void ConfigureServices(IServiceCollection services)
    {
        //Your Code
        services.AddScoped<ICultureService, CultureService>();
        //Your Code
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        //Your Code
        app.UseMiddleware<CultureMiddleware>();
        //Your Code
    }
_

Culture.razor:

_@page "/culture"
@inject ICultureService CultureService
<h1>Counter</h1>
<input type="text" @bind="currentDate" />

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private DateTime currentDate = DateTime.Now;
    private int currentCount = 0;

    private void IncrementCount()
    {
         if (currentCount < 2) CultureService.SetCCDateFormat();
        currentCount++;
    }
}
_

3)アプリケーションのデフォルトのカルチャを変更できる場合は、 ローカリゼーションミドルウェア を使用します。 Blazor Serverアプリは Localization&Globalization にローカリゼーションミドルウェアを使用しています。リクエストの現在のカルチャは localization Middleware で設定されます。ローカリゼーションミドルウェアは、_Startup.Configure_メソッドで有効になります。ローカリゼーションミドルウェアは、リクエストカルチャをチェックする可能性のあるミドルウェア(app.UseMvcWithDefaultRoute()など)の前に構成する必要があります。

例:

_var culture = new CultureInfo("en-US");
            culture.DateTimeFormat.ShortDatePattern = "dd-yyyy-MM";
            var supportedCultures = new List<CultureInfo> { culture };
        app.UseRequestLocalization(new RequestLocalizationOptions
        {
            DefaultRequestCulture = new RequestCulture(culture, culture),
            // Formatting numbers, dates, etc.
            SupportedCultures = supportedCultures,
            // UI strings that we have localized.
            SupportedUICultures = supportedCultures
        });
_
0
Ashiquzzaman