mono中XmlSerializer的问题

 在上一篇文章《ubuntu 8.10 server配置mono2.0.1运行asp.net 2.0 》中提到,在mono中进行自定义的XmlSerializer时发生异常。

发生异常的是在一个自定义的DataTable序列化(使用IXmlSerializable)中,异常信息是:

Cannot cast from source type to destination type.

Description: HTTP 500. Error processing request.

Stack Trace:

System.InvalidCastException: Cannot cast from source type to destination type.
  at System.Xml.XmlWriter.WriteValue (System.Object value) [0x00000] 
  at xDB.Examples.Employee.WriteXml (System.Xml.XmlWriter writer) [0x00000] 
  at System.Xml.Serialization.XmlSerializationWriter.WriteSerializable (IXmlSerializable serializable, System.String name, System.String ns, Boolean isNullable, Boolean wrapped) [0x00000] 
  at System.Xml.Serialization.XmlSerializationWriter.WriteSerializable (IXmlSerializable serializable, System.String name, System.String ns, Boolean isNullable) [0x00000] 
  at System.Xml.Serialization.XmlSerializationWriterInterpreter.WriteObject (System.Xml.Serialization.XmlTypeMapping typeMap, System.Object ob, System.String element, System.String namesp, Boolean isNullable, Boolean needType, Boolean writeWrappingElem) [0x00000] 
  at System.Xml.Serialization.XmlSerializationWriterInterpreter.WriteRoot (System.Object ob) [0x00000] 
  at System.Xml.Serialization.XmlSerializer.Serialize (System.Object o, System.Xml.Serialization.XmlSerializationWriter writer) [0x00000] 
  at System.Xml.Serialization.XmlSerializer.Serialize (System.Xml.XmlWriter writer, System.Object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces) [0x00000] 

通过分析,可以看出是XmlWriter在写入时候发生了类型转换的错误。通过跟踪错误,发现是在序列化Int16的类型时抛出的异常,难道是mono平台下不支持Int16类型?

于是我写了一段测试代码:

 

  1. public class Serializer : IHttpHandler
  2.     {
  3.         public void ProcessRequest(HttpContext context)
  4.         {
  5.             context.Response.ContentType = "text/xml";
  6.             XmlSerializer serializer = new XmlSerializer(typeof(Employee));
  7.             Int16 id = 12;
  8.             serializer.Serialize(context.Response.Output,new Employee(id,"xud",false));
  9.             
  10.         }
  11.         public bool IsReusable
  12.         {
  13.             get
  14.             {
  15.                 return false;
  16.             }
  17.         }
  18.     }
  19.     public class Employee : IXmlSerializable
  20.     {
  21.         public Employee()
  22.         {
  23.         }
  24.         public Employee(Int16 employeeId,string employeeName,bool deleted)
  25.         {
  26.             this.EmployeeId = employeeId;
  27.             this.EmployeeName = employeeName;
  28.             this.Deleted = deleted;
  29.         }
  30.         Int16 _employeeId;
  31.         public Int16 EmployeeId
  32.         {
  33.             get { return _employeeId; }
  34.             set { _employeeId = value; }
  35.         }
  36.         string _employeeName;
  37.         public string EmployeeName
  38.         {
  39.             get { return _employeeName; }
  40.             set { _employeeName = value; }
  41.         }
  42.         bool _deleted;
  43.         public bool Deleted
  44.         {
  45.             get { return _deleted; }
  46.             set { _deleted = value; }
  47.         }
  48.         #region IXmlSerializable 成员
  49.         public System.Xml.Schema.XmlSchema GetSchema()
  50.         {
  51.             throw new Exception("The method or operation is not implemented.");
  52.         }
  53.         public void ReadXml(XmlReader reader)
  54.         {
  55.             throw new Exception("The method or operation is not implemented.");
  56.         }
  57.         public void WriteXml(XmlWriter writer)
  58.         {
  59.             writer.WriteStartElement("Employee");
  60.             writer.WriteStartElement("EmployeeId");
  61.             writer.WriteValue(this.EmployeeId);
  62.             writer.WriteEndElement();
  63.             writer.WriteStartElement("EmployeeName");
  64.             writer.WriteValue(this.EmployeeName);
  65.             writer.WriteEndElement();
  66.             writer.WriteStartElement("Deleted");
  67.             writer.WriteValue(this.Deleted);
  68.             writer.WriteEndElement();
  69.             writer.WriteEndElement();
  70.             
  71.         }
  72.         #endregion
  73.     }
  74. }

 

编译运行后发现序列化完全正常!看来不是Int16的问题。

经过分析,忽然想起在DataTable中取值的时候取回的都是object类型,于是我又小小改动了一下代码:

  1. writer.WriteValue((object)this.EmployeeId);

编译...运行...呵呵,可爱的异常又出现了!!!

 

看来是mono平台在进行装箱、拆箱的时候有点小小的bug,同样的字符串转换,仅仅是包装不同?

通过修改我自己的代码,将其加上Convter.ToString(value)后,该异常得到解决。

 

在解决的这个问题后,我又直接使用DataTable自己的序列化功能,在mono下能正常使用。通过Reflector跟踪发现,在直接使用DataTable进行XmlSerializer的时候,是通过DataStorge类来进行字符串转换的,可惜由于是internal类,我们无法直接使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值