打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
字符串序列化时碰到的小问题
最近在使用.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
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Webservice SOAP传输序列化总结 以及webservice之序列化以及反序列化实例
Java实现对象序列化保存到数据库
一个经过改良的XMLHelper(包含了序列化,反序列化,创建xml文件,读取节点,C#对...
Android读写XML(下)——创建XML文档
.NET实体类序列化方法
XML与对象的序列化与反序列化
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服