最近在使用.NET當(dāng)中的序列化方法序列化字符串時(shí)碰到一個(gè)小問題。序列化時(shí)一切正常,反序列化時(shí)卻
碰到了問題。
先看代碼:
view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150.........
//對(duì)象定義
[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
//測(cè)試代碼
//普通的字符串
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!");
}
//對(duì)象定義
[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
//測(cè)試代碼
//普通的字符串
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!");
}
輸出結(jié)果:
TestClass1.TestMethod1 passed!
TestClass1.TestMethod2 failed!
Debug發(fā)現(xiàn)TestMethod1的序列化結(jié)果是:
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的序列化結(jié)果是:
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存為一個(gè)文件,然后用Visual Studio打開,會(huì)發(fā)現(xiàn)有以下的錯(cuò)誤提示:
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
這下我們明白了,原來就是:...這些個(gè)特殊字符在作怪。網(wǎng)上搜了一把,這個(gè)過程比較郁悶,不知道該用什么關(guān)鍵字去搜,后來直接在Google里試了一下“”發(fā)現(xiàn)前兩個(gè)就是和我相似的問題,其中第一個(gè)里面講到了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
這下就明白了,我反序列化的時(shí)候沒有直接用到XmlTextReader,而Normalization默認(rèn)是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 ;
好了,完事大吉!
最后奉上測(cè)試代碼:測(cè)試代碼
本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/shootsoft/archive/2009/07/31/4398675.aspx