¿Hay alguna forma de configurar la cultura para una aplicación completa? ¿Todos los hilos actuales y los hilos nuevos?


¿Hay alguna forma de configurar la cultura para una aplicación completa? ¿Todos los hilos actuales y los hilos nuevos?

Tenemos el nombre de la cultura almacenada en una base de datos, y cuando se inicia nuestra aplicación, lo hacemos

CultureInfo ci = new CultureInfo(theCultureString);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;

Pero, por supuesto, se "pierde" cuando queremos hacer algo en un nuevo hilo. ¿Hay una manera de establecer que CurrentCulture y CurrentUICulture para toda la aplicación? ¿Así que los nuevos hilos también tienen esa cultura? O es algún evento disparado cada vez que se crea un nuevo hilo que ¿Puedo conectarme?

Author: Robert Harvey, 2009-01-22

9 answers

En. NET 4.5, puede utilizar el CultureInfo.DefaultThreadCurrentCulture propiedad para cambiar la cultura de un AppDomain.

Para las versiones anteriores a la 4.5, debe usar reflexión para manipular la cultura de un AppDomain. Hay un campo estático privado en CultureInfo (m_userDefaultCulture en. NET 2.0 mscorlib, s_userDefaultCulture en.NET 4.0 mscorlib) que controla lo que CurrentCulture devuelve si un subproceso no ha establecido esa propiedad en sí mismo.

Esto no cambia la configuración regional del hilo nativo y probablemente no sea una buena idea enviar código que cambia la cultura de esta manera. Sin embargo, puede ser útil para las pruebas.

 177
Author: Austin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-26 08:25:43

Esto se pregunta mucho. Básicamente, no hay, no para. NET 4.0. Tienes que hacerlo manualmente al inicio de cada nuevo hilo (o función ThreadPool). Tal vez podría almacenar el nombre de la cultura (o simplemente el objeto de la cultura) en un campo estático para evitar tener que golpear la base de datos, pero eso es todo.

 34
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-10 11:31:32

Si está utilizando recursos, puede forzarlos manualmente:

Resource1.Culture = new System.Globalization.CultureInfo("fr"); 

En el administrador de recursos, hay un código generado automáticamente que es el siguiente:

/// <summary>
///   Overrides the current thread's CurrentUICulture property for all
///   resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
    get {
        return resourceCulture;
    }
    set {
        resourceCulture = value;
    }
}

Ahora cada vez que se refiere a su cadena individual dentro de este recurso, reemplaza la cultura (hilo o proceso) con el resourceCulture especificado.

Puede especificar el idioma como en "fr", "de", etc. o ponga el código de idioma como en 0x0409 para en-US o 0x0410 para it-IT. Para una lista completa de idiomas los códigos se refieren a: Identificadores de idioma y Locales

 17
Author: Reza S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-08 01:01:37

Para. net 4.5 y superior debe usar

var culture = new CultureInfo("en-US");
        CultureInfo.DefaultThreadCurrentCulture = culture;
        CultureInfo.DefaultThreadCurrentUICulture = culture;
 5
Author: Andreas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-13 13:52:18

En realidad, puede establecer la cultura de subprocesos predeterminada y la cultura de interfaz de usuario, pero solo con Framework 4.5 +

Puse en este constructor estático

static MainWindow()
{
  CultureInfo culture = CultureInfo
    .CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
  var dtf = culture.DateTimeFormat;
  dtf.ShortTimePattern = (string)Microsoft.Win32.Registry.GetValue(
    "HKEY_CURRENT_USER\\Control Panel\\International", "sShortTime", "hh:mm tt");
  CultureInfo.DefaultThreadCurrentUICulture = culture;
}

Y poner un punto de interrupción en el método Convert de un ValueConverter para ver lo que llegó al otro extremo. CultureInfo.CurrentUICulture dejó de ser en-US y se convirtió en su lugar en-AU completo con mi pequeño truco para que respete los entornos regionales para el patrón de tiempo corto.

Hurra, todo está bien en el mundo! O no. El el parámetro de cultivo pasado al método Convert es still en-US. ¿WTF?! Pero es un comienzo. Al menos de esta manera

  • puede corregir la cultura de la interfaz de usuario una vez cuando su aplicación se carga
  • siempre es accesible desde CultureInfo.CurrentUICulture
  • string.Format("{0}", DateTime.Now) utilizará su configuración regional personalizada

Si no puede usar la versión 4.5 del framework, deje de configurar CurrentUICulture como una propiedad estática de CultureInfo y establézcala como una propiedad estática de uno de los suyos clase. Esto no solucionará el comportamiento predeterminado de la cadena.Formatee o haga que StringFormat funcione correctamente en los enlaces, luego camine por el árbol lógico de su aplicación para recrear todos los enlaces en su aplicación y establecer su cultura de conversión.

 4
Author: Peter Wone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-19 13:29:34

Para ASP. NET5, es decir, ASPNETCORE, puede hacer lo siguiente en configure:

app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture(new CultureInfo("en-gb")),
    SupportedCultures = new List<CultureInfo>
    {
        new CultureInfo("en-gb")
    },
            SupportedUICultures = new List<CultureInfo>
    {
        new CultureInfo("en-gb")
    }
});

Aquí hay una serie de entradas de blog que dan más información.

 3
Author: Sean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-07 11:28:43

DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture también están presentes en Framework 4.0, pero son privadas. Usando Reflexión puedes fácilmente configurarlos. Afecta a todos los subprocesos donde CurrentCulture no está explícitamente establecido (también los subprocesos en ejecución).

Public Sub SetDefaultThreadCurrentCulture(paCulture As CultureInfo)
    Thread.CurrentThread.CurrentCulture.GetType().GetProperty("DefaultThreadCurrentCulture").SetValue(Thread.CurrentThread.CurrentCulture, paCulture, Nothing)
    Thread.CurrentThread.CurrentCulture.GetType().GetProperty("DefaultThreadCurrentUICulture").SetValue(Thread.CurrentThread.CurrentCulture, paCulture, Nothing)
End Sub
 2
Author: HCAxel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-20 09:50:34

Aquí está la solución para c # MVC:

  1. Primero: Cree un atributo personalizado y un método de anulación como este:

    public class CultureAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Retreive culture from GET
            string currentCulture = filterContext.HttpContext.Request.QueryString["culture"];
    
            // Also, you can retreive culture from Cookie like this :
            //string currentCulture = filterContext.HttpContext.Request.Cookies["cookie"].Value;
    
            // Set culture
            Thread.CurrentThread.CurrentCulture = new CultureInfo(currentCulture);
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(currentCulture);
        }
    }
    
  2. Segundo : En App_Start, encuentra FilterConfig.cs, agrega este atributo. (esto funciona para TODA la aplicación)

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            // Add custom attribute here
            filters.Add(new CultureAttribute());
        }
    }    
    

¡Eso es todo !

Si desea definir la cultura para cada controlador / acción en lugar de toda la aplicación, puede usar este atributo de la siguiente manera:

[Culture]
public class StudentsController : Controller
{
}

O:

[Culture]
public ActionResult Index()
{
    return View();
}
 2
Author: Meng Xue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-22 15:44:08

Esta respuesta es un poco de expansión para la gran respuesta de @rastating. Puede usar el siguiente código para todas las versiones de. NET sin preocupaciones:

    public static void SetDefaultCulture(CultureInfo culture)
    {
        Type type = typeof (CultureInfo);
        try
        {
            // Class "ReflectionContext" exists from .NET 4.5 onwards.
            if (Type.GetType("System.Reflection.ReflectionContext", false) != null)
            {
                type.GetProperty("DefaultThreadCurrentCulture")
                    .SetValue(System.Threading.Thread.CurrentThread.CurrentCulture,
                        culture, null);

                type.GetProperty("DefaultThreadCurrentUICulture")
                    .SetValue(System.Threading.Thread.CurrentThread.CurrentCulture,
                        culture, null);
            }
            else //.NET 4 and lower
            {
                type.InvokeMember("s_userDefaultCulture",
                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                    null,
                    culture,
                    new object[] {culture});

                type.InvokeMember("s_userDefaultUICulture",
                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                    null,
                    culture,
                    new object[] {culture});

                type.InvokeMember("m_userDefaultCulture",
                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                    null,
                    culture,
                    new object[] {culture});

                type.InvokeMember("m_userDefaultUICulture",
                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                    null,
                    culture,
                    new object[] {culture});
            }
        }
        catch
        {
            // ignored
        }
    }
}
 2
Author: polfosol ఠ_ఠ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-16 05:39:45