Webservice XML反序列化问题:大数double转decimal转换失败
问题分析:double转decimal在10位数值时XML序列化失败的原因
问题场景
- 服务端字段
MinimumOrderAmount为double类型,接收程序中对应字段定义为decimal类型 - 当服务端发送9位数值(如
999999999)时,接收程序正常处理;发送10位数值(如9999999999)时,抛出序列化错误,错误信息如下:
Exception thrown passed to this Web service: System.InvalidOperationException: There is an error in XML document (1, 3998). ---> System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAvailabilityService.Read13_VoucherDiscount(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAvailabilityService.Read90_RoomRate(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAvailabilityService.Read141_RoomStay(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAvailabilityService.Read142_AvailResponseSegment(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAvailabilityService.Read143_AvailabilityResponse(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAvailabilityService.Read191_AvailabilityResponse() at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
核心原因
问题本质不在于double到decimal的类型转换本身,而是XML序列化时double的输出格式与decimal解析规则不兼容:
- 9位数值正常的原因:9位十进制整数(≤999999999)属于
double的精确表示范围,且数值较小,XML序列化时会输出普通十进制字符串(如999999999),decimal的解析方法可直接处理该格式。 - 10位数值失败的原因:当
double值达到10位整数(如9999999999)时,.NET的XmlSerializer默认会将其序列化为科学计数法格式(如1E+10或9.999999999E+9)。而decimal的默认解析规则不支持科学计数法字符串,因此抛出FormatException。
解决方案验证
将服务端MinimumOrderAmount字段类型改为decimal后,XML序列化时会输出精确的十进制字符串(不会使用科学计数法),无论数值位数多少,接收端的decimal字段都能正常解析,这也验证了上述原因的正确性。
内容的提问来源于stack exchange,提问作者sysmenu
相关产品推荐
相关产品推荐

