最近在使用.NET当中的序列化方法序列化字符串时碰到一个小问题。序列化时一切正常,反序列化时却
碰到了问题。
先看代码:
view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150.........
//对象定义
[Serializable]
public class TestObject
{
public string Value { get; set; }
}
#region XmlFormatter 序列化类
/// <summary>
/// 序列化类
/// </summary>
public class XmlFormatter
{
public static string ToXml(object obj)
{
if (obj == null) return string.Empty;
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
try
{
XmlSerializer serializer = new XmlSerializer(obj.GetType(), string.Empty);
serializer.Serialize(sw, obj);
sw.Close();
return sb.ToString();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
return string.Empty;
}
}
public static object FromXml(string xml, Type type)
{
try
{
StringReader reader = new StringReader(xml);
XmlSerializer serializer = new XmlSerializer(type);
object obj = serializer.Deserialize(reader);
reader.Close();
return obj;
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
return null;
}
}
#endregion
//测试代码
//普通的字符串
static void TestMethod1()
{
TestObject expected = new TestObject() { Value = "Test 1234" };
string xmlString = XmlFormatter.ToXml(expected);
TestObject actual = new TestObject();
actual = (TestObject)XmlFormatter.FromXml(xmlString, actual.GetType());
if (actual != null && expected.Value == actual.Value)
Console.WriteLine("TestClass1.TestMethod1 passed!");
else Console.WriteLine("TestClass1.TestMethod1 failed!");
}
//包含特殊字符的字符串
static void TestMethod2()
{
TestObject expected = new TestObject() { Value = "Test1234" };
string xmlString = XmlFormatter.ToXml(expected);
TestObject actual = new TestObject();
actual = (TestObject)XmlFormatter.FromXml(xmlString, actual.GetType());
if (actual != null && expected.Value == actual.Value)
Console.WriteLine("TestClass1.TestMethod2 passed!");
else Console.WriteLine("TestClass1.TestMethod2 failed!");
}
//对象定义
[Serializable]
public class TestObject
{
public string Value { get; set; }
}
#region XmlFormatter 序列化类
/// <summary>
/// 序列化类
/// </summary>
public class XmlFormatter
{
public static string ToXml(object obj)
{
if (obj == null) return string.Empty;
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
try
{
XmlSerializer serializer = new XmlSerializer(obj.GetType(), string.Empty);
serializer.Serialize(sw, obj);
sw.Close();
return sb.ToString();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
return string.Empty;
}
}
public static object FromXml(string xml, Type type)
{
try
{
StringReader reader = new StringReader(xml);
XmlSerializer serializer = new XmlSerializer(type);
object obj = serializer.Deserialize(reader);
reader.Close();
return obj;
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
return null;
}
}
#endregion
//测试代码
//普通的字符串
static void TestMethod1()
{
TestObject expected = new TestObject() { Value = "Test 1234" };
string xmlString = XmlFormatter.ToXml(expected);
TestObject actual = new TestObject();
actual = (TestObject)XmlFormatter.FromXml(xmlString, actual.GetType());
if (actual != null && expected.Value == actual.Value)
Console.WriteLine("TestClass1.TestMethod1 passed!");
else Console.WriteLine("TestClass1.TestMethod1 failed!");
}
//包含特殊字符的字符串
static void TestMethod2()
{
TestObject expected = new TestObject() { Value = "Test1234" };
string xmlString = XmlFormatter.ToXml(expected);
TestObject actual = new TestObject();
actual = (TestObject)XmlFormatter.FromXml(xmlString, actual.GetType());
if (actual != null && expected.Value == actual.Value)
Console.WriteLine("TestClass1.TestMethod2 passed!");
else Console.WriteLine("TestClass1.TestMethod2 failed!");
}
输出结果:
TestClass1.TestMethod1 passed!
TestClass1.TestMethod2 failed!
Debug发现TestMethod1的序列化结果是:
view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
<?xml version="1.0" encoding="utf-16"?>
<TestObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Value>Test 1234</Value>
</TestObject>
<?xml version="1.0" encoding="utf-16"?>
<TestObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Value>Test 1234</Value>
</TestObject>
TestMethod2的序列化结果是:
view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
<?xml version="1.0" encoding="utf-16"?>
<TestObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Value>Test1234</Value>
</TestObject>
<?xml version="1.0" encoding="utf-16"?>
<TestObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Value>Test1234</Value>
</TestObject>
如果我们把TestMethod2的这段Xml存为一个文件,然后用Visual Studio打开,会发现有以下的错误提示:
Error 3 Character ' ', hexadecimal value 0x1 is illegal in XML documents. XMLFile2.xml 3 14 Miscellaneous Files
Error 4 Character ' ', hexadecimal value 0x2 is illegal in XML documents. XMLFile2.xml 3 19 Miscellaneous Files
Error 5 Character ' ', hexadecimal value 0x3 is illegal in XML documents. XMLFile2.xml 3 24 Miscellaneous Files
Error 6 Character ' ', hexadecimal value 0x4 is illegal in XML documents. XMLFile2.xml 3 29 Miscellaneous Files
这下我们明白了,原来就是:...这些个特殊字符在作怪。网上搜了一把,这个过程比较郁闷,不知道该用什么关键字去搜,后来直接在Google里试了一下“”发现前两个就是和我相似的问题,其中第一个里面讲到了MSDN里面的原文
参考这里吧:
http://bytes.com/groups/net-xml/176249-system-xml-xmldocument-parses-well-formed
http://www.codeguru.com/forum/archive/index.php/t-232348.html
特别是MSDN的原文:
http://msdn.microsoft.com/zh-cn/library/system.xml.xmltextreader.normalization(VS.80).aspx
这下就明白了,我反序列化的时候没有直接用到XmlTextReader,而Normalization默认是true,而是用的StringReader把字符串读取为流,只要把反序列化的方法稍微改改就行:
view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
TextReader tr = new StringReader(xml);
XmlTextReader reader = new XmlTextReader(tr);
reader.Normalization = false;
XmlSerializer serializer = new XmlSerializer(type);
object obj = serializer.Deserialize(reader);
tr.Close();
reader.Close();
return obj ;
TextReader tr = new StringReader(xml);
XmlTextReader reader = new XmlTextReader(tr);
reader.Normalization = false;
XmlSerializer serializer = new XmlSerializer(type);
object obj = serializer.Deserialize(reader);
tr.Close();
reader.Close();
return obj ;
好了,完事大吉!
最后奉上测试代码:测试代码
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/shootsoft/archive/2009/07/31/4398675.aspx
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。