web-dev-qa-db-fra.com

Comment modifier le format de date de culture actuel dans Blazor (serveur)?

globalisation et localisation ASP.NET Core Blazor états:

Blazor @bind fonctionnalité effectue des formats et analyse les valeurs pour l'affichage en fonction de la culture actuelle de l'utilisateur.
La culture actuelle est accessible depuis le System.Globalization.CultureInfo.CurrentCulture property.

La déclaration est vraie, mais le problème est que la culture doit être définie juste avant d'être utilisée (ou peut-être chaque fois que le DOM est actualisé).

Pour la démonstration, j'utiliserai une application de compteur blazor standard. Modifions 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;
        }
    }

} 

Le résultat est:

  • lorsque la page est rendue pour la première fois, la zone de texte contient la date mise en forme par la culture par défaut du serveur.
  • lorsque le bouton est enfoncé la première et la deuxième fois, le format de la date est dd-yyyy-m

J'ai tenté de modifier la date dans OnAfterRender, OnInitialized sans succès. La seule solution utilisable, j'ai trouvé, est de définir le format sur la mendicité du balisage de rasoir.

@{Utils.SetCCDateFormat();}

Existe-t-il un moyen de modifier CurrentCulture pour devenir persistant dans le circuit blazor?

Le comportement observé est-il correct ou s'agit-il d'un bug?

Modifier

Ce que j'ai trouvé jusqu'à présent

Il est possible de définir des propriétés de culture (CultureInfo.CurrentCulture) dans un middleware avant le point de terminaison blazor est créé et les modifications sont persistantes pendant la durée de vie du circuit. Lorsque nous modifions CurrentCulture dans les méthodes du cycle de vie des composants, le changement n'est que temporaire (jusqu'à la fin de la méthode).

Ma compréhension du problème est

  • Lorsqu'un circuit est créé, il stocke la culture actuelle quelque part
  • Un serveur a un nombre limité de threads
  • Un thread est affecté à un circuit lorsque cela est nécessaire et la culture actuelle est définie par ce qui a été stocké au début
  • Il est possible de modifier le CurrentCulture, mais cela n'influence pas le stockage des paramètres et donc lorsqu'une autre méthode d'événement est appelée (autre thread), la culture d'origine est utilisée.

Il semble donc que la question soit: Comment modifier les paramètres de culture du circuit alors qu'il est déjà créé?

Peut-être que ce n'est pas possible et qu'il est nécessaire de faire une actualisation complète (recommencer une requête avec navigation) et d'utiliser un middleware pour définir une culture modifiée. Une existence de stockage de culture n'est que ma conjecture et je n'ai aucune référence pour la soutenir.

Un grand merci à Tyeth et Ashiquzzaman pour leur aide, mais je ne considère pas leurs tentatives comme une réponse.

9
IvanH

La deuxième partie de la réponse d'Ashiquzzaman (après OU) fait allusion au bon chemin à prendre.

Le middleware de localisation ASP.Net Core intégré sera votre nouveau meilleur ami: https://docs.Microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-3.1#localization- middleware

Vous pouvez compter sur le CookieRequestCultureProvider inclus par défaut, et en définissant un cookie pour vos utilisateurs connectés sur une base par utilisateur (je suggère lors de la connexion que vous aurez accès aux préférences stockées des utilisateurs alors), vous pouvez remplacer la langue demandée par le navigateur par défaut ( ou système par défaut en dernier recours).

L'ordre répertorié des RequestLocalizationProviders est sur ce lien publié et suggère que la chaîne de requête peut remplacer le cookie qui peut remplacer la préférence du navigateur:

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

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider **
  3. AcceptLanguageHeaderRequestCultureProvider

Le CookieRequestCultureProvider DefaultCookieName renvoie le nom de cookie par défaut utilisé pour suivre les informations de culture préférées de l'utilisateur. Le nom du cookie par défaut est .AspNetCore.Culture.

Le format du cookie est c =% LANGCODE% | uic =% LANGCODE%, où c est Culture et uic est UICulture, par exemple:

c=en-UK|uic=en-US

Vous devriez certainement lire la section Blazor sur la mondialisation et la localisation comme suggéré par Ashiquzzaman: https://docs.Microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-3.1

1
Tyeth

1) Utilisez middleware

Exemple:

    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) middleware personnalisé avec service:

Service:

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;
    }
}

Intergiciel:

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);
    }
}

Démarrage:

    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) Si vous pouvez changer la culture par défaut de l'application, utilisez middleware de localisation . Les applications Blazor Server utilisent le middleware de localisation pour Localisation et globalisation . La culture actuelle sur une requête est définie dans le middleware de localisation . L'intergiciel de localisation est activé dans la méthode Startup.Configure. Le middleware de localisation doit être configuré avant tout middleware susceptible de vérifier la culture de la requête (par exemple, app.UseMvcWithDefaultRoute()).

Exemple:

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