У меня есть два nvarchar поля в базе данных для хранения DataType и DefaultValue, и я сделал, чтобы DataType Удвоил и оценил как 65,89875 в английском формате.
Теперь я хочу, чтобы пользователь видел, значение согласно выбранному формату языка браузера (65.89875 на английском языке должен быть отображен как 65,89875 на немецком языке). Теперь, если пользователь редактирует от немецкого формата до 65,89875, который является 65,89875 эквивалентными на английском языке и другими пользовательскими представлениями от английского браузера, он стал 6589875.
Это происходит, потому что в базе данных это было сохранено как 65,89875 в nvarchar столбце и при преобразовании с помощью английской культуры это становится 6589875, так как это рассматривает ,
как разделитель, который является десятичным оператором для немецкого языка.
Как я получаю эту работу для всех браузеров?
Вам необходимо определить единую локаль, которую вы будете использовать для данных, хранящихся в базе данных, инвариантная культура существует именно для этой цели.
Когда вы отображаете преобразование в собственный тип, а затем форматирование в соответствии с культурой пользователя.
Например. для отображения:
string fromDb = "123.56";
string display = double.Parse(fromDb, CultureInfo.InvariantCulture).ToString(userCulture);
для сохранения:
string fromUser = "132,56";
double value;
// Probably want to use a more specific NumberStyles selection here.
if (!double.TryParse(fromUser, NumberStyles.Any, userCulture, out value)) {
// Error...
}
string forDB = value.ToString(CultureInfo.InvariantCulture);
PS. Само собой разумеется, что использование столбца с типом данных, который соответствует данным, было бы даже лучше (но иногда применяется устаревшее).
У меня есть эта функция в моем наборе инструментов несколько лет назад (все имена функций и переменных запутаны и смешаны с испанским и английским, извините за это).
Он позволяет пользователю использовать ,
и .
для разделения десятичных знаков и постарается сделать все возможное, если используются оба символа.
Public Shared Function TryCDec(ByVal texto As String, Optional ByVal DefaultValue As Decimal = 0) As Decimal
If String.IsNullOrEmpty(texto) Then
Return DefaultValue
End If
Dim CurAsTexto As String = texto.Trim.Replace("$", "").Replace(" ", "")
''// You can probably use a more modern way to find out the
''// System current locale, this function was done long time ago
Dim SepDecimal As String, SepMiles As String
If CDbl("3,24") = 324 Then
SepDecimal = "."
SepMiles = ","
Else
SepDecimal = ","
SepMiles = "."
End If
If InStr(CurAsTexto, SepDecimal) > 0 Then
If InStr(CurAsTexto, SepMiles) > 0 Then
''//both symbols was used find out what was correct
If InStr(CurAsTexto, SepDecimal) > InStr(CurAsTexto, SepMiles) Then
''// The usage was correct, but get rid of thousand separator
CurAsTexto = Replace(CurAsTexto, SepMiles, "")
Else
''// The usage was incorrect, but get rid of decimal separator and then replace it
CurAsTexto = Replace(CurAsTexto, SepDecimal, "")
CurAsTexto = Replace(CurAsTexto, SepMiles, SepDecimal)
End If
End If
Else
CurAsTexto = Replace(CurAsTexto, SepMiles, SepDecimal)
End If
''// At last we try to tryParse, just in case
Dim retval As Decimal = DefaultValue
Decimal.TryParse(CurAsTexto, retval)
Return retval
End Function
С помощью FormatProviders вы можете преобразовать значение, предоставляемое пользователем, в значение типа double и сохранить его снова как nvarchar. CultureInfo - это типичный FormatProvider. Предполагая, что вы знаете культуру, с которой работаете,
System.Globalization.CultureInfo EnglishCulture = new System.Globalization.CultureInfo("en-EN");
System.Globalization.CultureInfo GermanCulture = new System.Globalization.CultureInfo("de-de");
будет достаточно для выполнения необходимого преобразования, например:
double val;
if(double.TryParse("65,89875", System.Globalization.NumberStyles.Float, GermanCulture, out val))
{
string valInGermanFormat = val.ToString(GermanCulture);
string valInEnglishFormat = val.ToString(EnglishCulture);
}
if(double.TryParse("65.89875", System.Globalization.NumberStyles.Float, EnglishCulture, out val))
{
string valInGermanFormat = val.ToString(GermanCulture);
string valInEnglishFormat = val.ToString(EnglishCulture);
}