Как изменить текущий формат даты культуры в Blazor (сервер)? - PullRequest
6 голосов
/ 18 марта 2020

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

} 

В результате:

  • при первом отображении страницы текстовое поле содержит дату, отформатированную по умолчанию на сервере.
  • когда кнопка нажата первый и второй раз, формат даты - dd-yyyy-m

Я попытался изменить дату в OnAfterRender, OnInitialized, но безуспешно. Я обнаружил, что единственное полезное решение - это установка формата в начале разметки бритвы.

@{Utils.SetCCDateFormat();}

Есть ли способ изменить CurrentCulture, чтобы он стал постоянным в схеме блейзора?

Является ли наблюдаемое поведение правильным или это ошибка?

Редактировать

То, что я нашел до сих пор

Можно установить свойства культуры (CultureInfo.CurrentCulture) в промежуточном программном обеспечении * За 1046 * до создается конечная точка блейзера, и изменения сохраняются в течение всего срока службы цепи. Когда мы модифицируем CurrentCulture в методах жизненного цикла компонентов, изменение носит временный характер (до конца метода).

Мое понимание проблемы:

  • Когда создается цепь где-то хранится текущая культура
  • Сервер имеет ограниченное количество потоков
  • При необходимости поток назначается в цепь, а текущая культура задается тем, что было сохранено в начале
  • Можно изменить CurrentCulture, но это не влияет на хранилище настроек, поэтому при вызове другого метода события (другого потока) используется оригинальная культура.

Таким образом, кажется, что вопрос: Как изменить настройки культуры схем, когда она уже создана?

Может быть, это невозможно, и это необходимо выполнить полную ссылку sh (снова запустить запрос с помощью навигации) и использовать промежуточное ПО для установки измененной культуры. Существование хранилища культур - только моя гипотеза, и у меня нет никаких ссылок, чтобы поддержать это.

Большое спасибо Tyeth и Ashiquzzaman за помощь, но я не принимаю их попытки как ответ.

Ответы [ 2 ]

1 голос
/ 12 апреля 2020

Вторая часть ответа Ашикззамана (после ИЛИ) намекает на правильный путь для выбора.

Встроенное ASP. Net Промежуточное программное обеспечение для локализации ядра будет вашим новым лучшим другом: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-3.1#localization -middleware

Вы можете положиться на включенный по умолчанию CookieRequestCultureProvider и установить повар ie для ваших зарегистрированных пользователей для каждого пользователя (я предлагаю при входе в систему, поскольку у вас будет доступ к сохраненным предпочтениям пользователей), вы можете переопределить язык, запрашиваемый браузером по умолчанию (или системное значение по умолчанию в качестве крайней меры).

Перечисленный порядок RequestLocalizationProviders находится на той ссылке, опубликованной и предполагает, что строка запроса может переопределить повар ie, который может переопределить настройки браузера:

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

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider **
  3. AcceptLanguageHeaderRequestCultureProvider

CookieRequestCultureProvider DefaultCookieName retur ns имя повара по умолчанию ie, используемое для отслеживания предпочтительной информации о культуре пользователя. Повар по умолчанию ie имя .AspNetCore.Culture.

Формат повара ie: c =% LANGCODE% | uic =% LANGCODE%, где c - Культура, а пользовательский интерфейс c - UICulture, например:

c=en-UK|uic=en-US

Обязательно прочитайте блазорский раздел, посвященный глобализации и локализации, как предлагает Ашикззаман: https://docs.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-3.1

0 голосов
/ 10 апреля 2020

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) Если вы можете изменить стандартную культуру приложения, используйте Локализация Middleware . В приложениях Blazor Server используется Middleware Localization для Локализация и глобализация . Текущая культура по запросу устанавливается в промежуточном программном обеспечении для локализации . Промежуточное программное обеспечение для локализации включено в методе 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
        });
...