.net - istringlocalizer - net core culture
¿Cómo puedo anular el formato de moneda para la cultura actual de una aplicación web ASP.NET? (2)
Los separadores de decimales y mil de moneda para la región en-ZA son '','' y '''', respectivamente, pero los separadores de uso común son ''.'' para decimal, más mi usuario quiere '','' para el separador de miles. Deseo establecerlos globalmente, de modo que solo tenga que utilizar la cadena de formato {0:C}
para todos mis campos de moneda, sin tener que hacer ninguna ToString
explícita de Format
o de ToString
.
Preferiría poder hacer esto sin cambiar la configuración cultural en el servidor web, ya que también necesito establecer los lugares decimales para la moneda en cero, ya que no se quieren centavos al informar sobre estimaciones de R100k y superiores, etc. No lo haría. No quiero establecer arbitrariamente toda la cultura en cero lugares, solo uno para esta aplicación.
En comentarios a su respuesta a esta pregunta , Jon Skeet sugiere clonar la cultura actual y establecer y cambiar la configuración requerida. He hecho esto de la siguiente manera:
void Application_Start(object sender, EventArgs e)
{
var newCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
newCulture.NumberFormat.CurrencyDecimalSeparator = ".";
newCulture.NumberFormat.CurrencyGroupSeparator = ",";
}
Sin embargo, ¿cómo puedo activar esa nueva cultura para todas las solicitudes que maneja la aplicación desde este momento? ¿Hay alguna otra forma de lograr lo que deseo hacer?
Puede usar el evento Application_BeginRequest
para establecer la cultura para cada solicitud. Evento interno:
var newCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
newCulture.NumberFormat.CurrencyDecimalSeparator = ".";
newCulture.NumberFormat.CurrencyGroupSeparator = ",";
System.Threading.Thread.CurrentThread.CurrentCulture = newCulture;
System.Threading.Thread.CurrentThread.CurrentUICulture = newCulture;
Después de hacer muchas preguntas y hacer muchos experimentos, he decidido que es seguro afirmar que la única forma de hacerlo es usar controles derivados de los controles listos para usar y hacer tu propio formato con un objeto cultural personalizado. Obtenga su control de, por ejemplo, BoundField
y proporcione su propio FormatProvider
:
public class BoundReportField : BoundField
{
protected virtual string GetDefaultFormatString(FieldFormatTypes formatType)
{
var prop = typeof(FormatStrings).GetProperty(formatType.ToString()).GetValue(null, null);
return prop.ToString();
}
protected virtual IFormatProvider GetFormatProvider(FieldFormatTypes formatType)
{
var info = (CultureInfo)CultureInfo.CurrentCulture.Clone();
info.NumberFormat.CurrencyDecimalDigits = 0;
info.NumberFormat.CurrencySymbol = "R";
info.NumberFormat.CurrencyGroupSeparator = ",";
info.NumberFormat.CurrencyDecimalSeparator = ".";
return info;
}
private FieldFormatTypes _formatType;
public virtual FieldFormatTypes FormatType
{
get { return _formatType; }
set
{
_formatType = value;
DataFormatString = GetDefaultFormatString(value);
}
}
protected override string FormatDataValue(object dataValue, bool encode)
{
// TODO Consider the encode flag.
var formatString = DataFormatString;
var formatProvider = GetFormatProvider(_formatType);
if (string.IsNullOrWhiteSpace(formatString))
{
formatString = GetDefaultFormatString(_formatType);
}
return string.Format(formatProvider, formatString, dataValue);
}
}
Voy a publicar un artículo más adelante con todos los detalles sangrientos.