【问题标题】:Serialize/Deserialize an specific type array to xml将特定类型的数组序列化/反序列化为 xml
【发布时间】:2018-01-09 06:15:07
【问题描述】:

我在序列化/反序列化特定对象数组时遇到问题。

[System.SerializableAttribute()] 
public class ctyp_HT
{
   private Operationalmessage[] opm;
   [System.Xml.Serialization.XmlElementAttribute("OpMessages", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
   public Operationalmessage[] P_OpMessages{
      get {
          return this.opm;
      }
      set {
          this.opm= value;
      }
   }
}

使用此属性中的 set{},序列化进程会在运行时崩溃。没有 set{} 它会工作,但为什么。该类被标记为 [System.SerializableAttribute()]。 这是我与通用函数结合使用的函数调用:

SerializeObject<ctyp_HT>(objInstance);

public static string SerializeObject<T>(T serializableObject)
    {
        if (serializableObject == null) { return string.Empty; }

        try
        {
            XmlDocument xmlDocument = new XmlDocument();
            XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
            using (MemoryStream stream = new MemoryStream())
            {
                serializer.Serialize(stream, serializableObject);
                stream.Position = 0;
                xmlDocument.Load(stream);
                stream.Close();
            }
            return xmlDocument.InnerXml;
        }
        catch (Exception ex)
        {
            return (ex.Message + "\n" + ex.InnerException.Message + "\n" + ex.StackTrace + "\n\n\n" + ex.InnerException.StackTrace);
        }
    }

我做错了什么?谢谢帮忙。

在第一条评论后编辑:

[System.SerializableAttribute()]
public class Operationalmessage : I_Information
{
   private object objGen;
[System.Xml.Serialization.XmlElementAttribute("OPEN", typeof(ctyp_intEndlage_AUF), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlElementAttribute("CLOSE", typeof(ctyp_intEndlage_ZU), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlElementAttribute("BETWEEN", typeof(ctyp_intEndlage_ZWISCHEN), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("objIdentifier")]
   public object P_objGen
  {
     get { return objGen; }
     set { objGen = value; }
  }
  private UnnamedChoice0 objIdentifier;
  [System.Xml.Serialization.XmlIgnoreAttribute()]
  public UnnamedChoice0 P_objIdentifier
  {
     get { return objIdentifier; }
     set { objIdentifier = value; }
  }
  [System.Xml.Serialization.XmlIgnoreAttribute()]
  public string P_Info
  {
     get
     {
        if(objGen is I_Information) return objIdentifier + "(" + ((I_Information)objGen).P_Info + ")"; 
        else return objIdentifier + "(" + objGen + ")";
     }
  }
}

未命名的选择是一个公共枚举。由于我的生成器,类 ctyp_intEndlage_Auf/ZU/Zwischen 都相同但名称不同。

    [System.SerializableAttribute()]
public class ctyp_intEndlage_AUF : I_Information
{
   private ctyp_Infoquelle_BOOL1_In Informationsquelle = null;
   [System.Xml.Serialization.XmlElementAttribute("Informationsquelle", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
   public ctyp_Infoquelle_BOOL1_In P_Informationsquelle
   {
      get { return Informationsquelle; }
      set { Informationsquelle = value; }
   }
   private string Extension = "036";
   [System.Xml.Serialization.XmlElementAttribute("Extension", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
   public string P_Extension
   {
      get { return Extension; }
      set { Extension = value; }
   }
   public string P_Info
   {
      get 
      {
         string result = "";         return "( " + Informationsquelle.P_Info + " "  + Extension + " "  + result + ")"; 
      }
   }
   public ctyp_intEndlage_AUF() 
   {
      Informationsquelle = new ctyp_Infoquelle_BOOL1_In();
   }
}

和最后一个类 bool1

    [System.SerializableAttribute()]
public class ctyp_Infoquelle_BOOL1_In : I_Information
{
   private object objGen;
   [System.Xml.Serialization.XmlElementAttribute("HardwareEingang", typeof(string), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
   [System.Xml.Serialization.XmlElementAttribute("KoppelEingang", typeof(string), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
   [System.Xml.Serialization.XmlChoiceIdentifierAttribute("objIdentifier")]
   public object P_objGen
   {
      get { return objGen; }
      set { objGen = value; }
   }
   private UnnamedChoice1 objIdentifier;
   [System.Xml.Serialization.XmlIgnoreAttribute()]
   public UnnamedChoice1 P_objIdentifier
   {
      get { return objIdentifier; }
      set { objIdentifier = value; }
   }
   public string P_Info
   {
      get
      {
         if(objGen is I_Information) return objIdentifier + "(" + ((I_Information)objGen).P_Info + ")"; 
         else return objIdentifier + "(" + objGen + ")";
      }
   }
   public ctyp_Infoquelle_BOOL1_In() 
   {
   }
}

属性 P_Info 在 I_Information 接口中声明。 对不起所有的德国名字=)。

【问题讨论】:

  • 你能加入Operationalmessage吗?没有代码很难判断出什么问题。顺便说一句:对于数组,您希望使用 XmlArrayXmlArrayItem 属性而不是 XmlElement(除非您不希望使用元素包装集合)。
  • 当你序列化的时候属性必须是公开的而不是私有的

标签: c# xml wpf serialization exception-handling


【解决方案1】:

我用正确的代码创建了 .net fiddle:https://dotnetfiddle.net/67evia

您的问题是在 System.Xml.Serialization.XmlChoiceIdentifierAttribute 类中使用私有字段。

你有:

[System.Xml.Serialization.XmlChoiceIdentifierAttribute("objIdentifier")]

它必须是:

[System.Xml.Serialization.XmlChoiceIdentifierAttribute("P_objIdentifier")]

我还在您的序列化程序方法中扩展了错误日志记录,以正确读取所有异常。

catch (Exception ex)
{
    var log = (ex.Message + "\n" + ex.StackTrace );
    var extemp = ex.InnerException;
    while (extemp != null)
    {
        log += "\n\n\n" + extemp.Message + "\n" + extemp.StackTrace;
        extemp = extemp.InnerException;
    }
    return log;
}

【讨论】:

  • 非常感谢您对我的问题进行的出色调查。我想我是盲人,但错误信息并没有帮助我。问题已解决,非常感谢!
  • 附录:这种扩展的异常日志记录是我需要的工具。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
相关资源
最近更新 更多