c# - 反序列化报错:Input string was not in a correct format
来源:互联网 发布:淘宝买的袖剑能杀人吗 编辑:程序博客网 时间:2024/05/18 00:12
1. 问题:
一直没有仔细考虑过反序列化Nullable字段的问题,貌似也没发现过问题,因为序列化及反序列化如果由同一个人或Team写的话,会掩盖这个问题。
请大家看一下代码:
public class A{ public String Name { get; set; } public decimal? Value {get; set;} public bool ShouldSerializeValue() { return this.Value.HasValue; }}class Program { static void Main(string[] args) { string xmlContent = @"<A> <Name>aa</Name> <Value/> </A>"; // DeserializeXML方法请参照: http://blog.csdn.net/yuxuac/article/details/16830589 A a2 = Serializer.DeserializeXML<A>(xmlContent); Console.ReadLine(); } }
大家觉得代码能正确执行么?
答案是不能,错误信息为:Input string was not in a correct format。
2. 原因分析:
原因是什么?
让我们先从ShouldSerialize()方法讲起, 此方法的作用从其方法签名可见一二, 使用此方法可以控制是否序列化某些字段(当然,通常情况下用来会控制Nullable类型的字段在什么情况下被序列化)。
请看以下示例:
1. 如果直接序列化一个A对象,故意不给Value赋值。
A a = new A(){ Name = "aa"};string str = Util.SerializeXML(a);
XML会长这个样子,我们定义了方法ShouldSerializeValue(),其定义中明确描述了,只有Value有值的情况下才序列化,因此Value节点没有被序列化:
<?xml version="1.0" encoding="utf-16"?><A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Name>aa</Name></A>
2. 如果我们去掉A中的ShouldSerializeValue() 方法:
public class A { public String Name { get; set; } public decimal? Value {get; set;} }A a = new A(){ Name = "aa"}; string str = Serializer.SerializeXML(a)
XML会长这个样子,Value节点还存在(包含属性:xsi:nil="true"),这是我们不定义ShouldSerialize方法的时候的默认情况。
<?xml version="1.0" encoding="utf-16"?><A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Name>aa</Name> <Value xsi:nil="true" /></A>
因此,ShouldSerializeXX()的作用,即在序列化时,控制是否序列化指定字段。它的用法是ShouldSerializeXX(),此处的XX即你定义的字段名称。
再看我们上面的代码,有ShouldSerializeValue()方法,反序列化的时候,是否此方法还起作用呢?(此时我们的XML中有一个<Value/>节点,没有值。)我曾想当然的以为它在反序列化的时候也会work。
但答案是不行,而且还报错。原因是什么?
原因是:在反序列化的时候,请注意我们的xmlContent变量定义的XML内容,<Value/>节点存在;事实上反序列化无法识别没有被标记为xsi:nil="true"的可空对象,它会认为这是个非法的值。
或许将来会加上ShouldDeserializeXX()方法来解决这个问题。
3. 解决办法:
原因找到了,怎么解决?有两个方法:
1. 去掉Value节点。
2. 人为控制反序列化的过程(就是修改Value字段的定义,控制字符串怎么赋值给Nullable的对象,Nullable对象怎么赋值到字符串),修正代码如下:
public class A { public String Name { get; set; } public bool ShouldSerializeValue() { return this.Value.HasValue; } [XmlIgnore] public decimal? Value { get; set; } [XmlElement(ElementName = "Value")] public string ValueStr { get { if (this.Value.HasValue) return this.Value.Value.ToString("f"); else return string.Empty; } set { if (string.IsNullOrEmpty(value)) this.Value = null; else this.Value = decimal.Parse(value); } } }
此时我们在执行上文提到的Main方法,发现不会报错了,而且Value的值被很好地处理了。
- c# - 反序列化报错:Input string was not in a correct format
- Input string was not in a correct format. 错误解析
- A file with the correct name was found in this directory, but it is not the correct one.
- Input a string in Java
- The following URL schemes found in your app are not in the correct format 解决方案
- javax.xml.ws.soap.SOAPFaultException: A specified parameter was not correct: deviceKey
- format not a string literal and no format arguments
- format not a string literal and no format arguments
- format not a string literal and no format arguments
- error: format not a string literal and no format arguments
- format not a string literal and no format arguments
- format not a string literal and no format arguments
- error: format not a string literal and no format arguments
- “error: request for member 'tcount' in something not a structure or union,warning: format not a string literal and no format arg
- not recognize input near 'row' 'format' 'delimited' in select clause
- Format string is not a string literal (potentially insecure)
- DOS format was specified but only a single line feed character was found, not 2
- DOS format was specified but only a single line feed character was found, not 2
- 前端面试题
- GNSS信号捕获(1)
- C#编码规范
- 地质年代
- Java annotation详解
- c# - 反序列化报错:Input string was not in a correct format
- 自拟三子棋小游戏
- 生产者消费者问题(代码实现)
- Object类-----简单描述
- 解决studio导入eclipse乱码问题
- 华为支持ONOS@IETF Hackathon——标准与开源的完美邂逅
- PULL解析XML小实例
- Java烧脑驴游(十三)--方法
- iOS开发 - 第04篇 - 网络 - 07 - JS & jQuery & UIWebView和JS交互