放TryToParseNumericType = true
JsConfig.TryToParseNumericType = true
如果您希望 ServiceStack.Text 确定类型之外的类型,则需要设置decimal
。
控制原始类型:
关于控制您的数字被解析到的类型,我提交了更改以改进 ServiceStack.Text,以提供将包含在即将发布的版本中的此类功能,并提交。
所以你将能够做到:
JsConfig.TryParseNumericType = true;
JsConfig.ParsePrimitiveFloatingPointTypes = ParseAsType.Single;
JsConfig.ParsePrimitiveIntegerTypes = ParseAsType.Int32 | ParseAsType.Int64;
正如您所指出的那样,该配置将返回 aInt32
而不是byte
a 。而不是decimal
你会得到一个float
.
以供参考:
下面是更新的原始解析方法,它现在应该提供更好的控制,以及在无法解析类型时更好的回退选项。
public static object ParsePrimitive(string value)
{
if (string.IsNullOrEmpty(value)) return null;
bool boolValue;
if (bool.TryParse(value, out boolValue)) return boolValue;
// Parse as decimal
decimal decimalValue;
var acceptDecimal = JsConfig.ParsePrimitiveFloatingPointTypes.HasFlag(ParseAsType.Decimal);
var hasDecimal = decimal.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out decimalValue);
// Check if the number is an Primitive Integer type given that we have a decimal
if(hasDecimal && decimalValue == decimal.Truncate(decimalValue))
{
// Value is a whole number
if (JsConfig.ParsePrimitiveIntegerTypes.HasFlag(ParseAsType.Byte) && decimalValue <= byte.MaxValue && decimalValue >= byte.MinValue) return (byte)decimalValue;
if (JsConfig.ParsePrimitiveIntegerTypes.HasFlag(ParseAsType.SByte) && decimalValue <= sbyte.MaxValue && decimalValue >= sbyte.MinValue) return (sbyte)decimalValue;
if (JsConfig.ParsePrimitiveIntegerTypes.HasFlag(ParseAsType.Int16) && decimalValue <= Int16.MaxValue && decimalValue >= Int16.MinValue) return (Int16)decimalValue;
if (JsConfig.ParsePrimitiveIntegerTypes.HasFlag(ParseAsType.UInt16) && decimalValue <= UInt16.MaxValue && decimalValue >= UInt16.MinValue) return (UInt16)decimalValue;
if (JsConfig.ParsePrimitiveIntegerTypes.HasFlag(ParseAsType.Int32) && decimalValue <= Int32.MaxValue && decimalValue >= Int32.MinValue) return (Int32)decimalValue;
if (JsConfig.ParsePrimitiveIntegerTypes.HasFlag(ParseAsType.UInt32) && decimalValue <= UInt32.MaxValue && decimalValue >= UInt32.MinValue) return (UInt32)decimalValue;
if (JsConfig.ParsePrimitiveIntegerTypes.HasFlag(ParseAsType.Int64) && decimalValue <= Int64.MaxValue && decimalValue >= Int64.MinValue) return (Int64)decimalValue;
if (JsConfig.ParsePrimitiveIntegerTypes.HasFlag(ParseAsType.UInt64) && decimalValue <= UInt64.MaxValue && decimalValue >= UInt64.MinValue) return (UInt64)decimalValue;
return null;
}
// Value is a floating point number
// Return a decimal if the user accepts a decimal
if(hasDecimal && acceptDecimal)
return decimalValue;
// Parse as double if decimal failed or user wants a double
double doubleValue = 0;
var acceptDouble = JsConfig.ParsePrimitiveFloatingPointTypes.HasFlag(ParseAsType.Double);
var hasDouble = (!hasDecimal || acceptDouble) && double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
// Return a double if the user accepts a double
if(acceptDouble && hasDouble)
return doubleValue;
// Parse as float
float floatValue;
var acceptFloat = JsConfig.ParsePrimitiveFloatingPointTypes.HasFlag(ParseAsType.Single);
var hasFloat = float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatValue);
// Return a float if the user accepts a float
if(acceptFloat && hasFloat)
return floatValue;
// Default to decimal, then double , then float or null
if(hasDecimal) return decimalValue;
if(hasDouble) return doubleValue;
if(hasFloat) return floatValue;
return null;
}