C# · 12月 23, 2021

c# – .NET XML序列化错误(反映类型有错误)

是的,我知道非常通用的标题,但我现在要解释.

鉴于下面的类定义,有人可以解释为什么我在调用Serialize()方法时会遇到此异常.

{“有一个错误反映了’FNM.MISMO_3_0.FOREIGN_OBJECT’类型.”}

{“选择标识符’ItemsElementName’的类型与’Items’的类型不一致.请使用System.Collections.Generic.List`1 [[MISMO_3_0.ItemsChoiceType,MISMO_3_0,Version = 1.0.0.0,Culture = neutral,PublicKeyToken]的数组= NULL]].“}

谢谢,
斯蒂芬

[System.CodeDom.Compiler.GeneratedCodeAttribute(“System.Xml”,”4.0.30319.225″)][System.SerializableAttribute()][System.Diagnostics.DebuggerStepThroughAttribute()][System.ComponentModel.DesignerCategoryAttribute(“code”)][System.Xml.Serialization.XmlTypeAttribute(Namespace = “http://www.mismo.org/residential/2009/schemas”)][System.Xml.Serialization.XmlRootAttribute(Namespace = “http://www.mismo.org/residential/2009/schemas”,IsNullable = true)]public partial class FOREIGN_OBJECT{ private List<object> itemsField; private List<ItemsChoiceType> itemsElementNameField; private MISMOresourceLink typeField; private bool typeFieldSpecified; private string roleField; private string titleField; private string labelField; private string sequenceNumberField; private static System.Xml.Serialization.XmlSerializer serializer; public FOREIGN_OBJECT() { this.itemsElementNameField = new List<ItemsChoiceType>(); this.itemsField = new List<object>(); } [System.Xml.Serialization.XmlElementAttribute(“CharacterEncodingSetType”,typeof(CharacterEncodingSetEnum),Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“CharacterEncodingSetTypeOtherDescription”,typeof(MISMOString),Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“EXTENSION”,typeof(EXTENSION),Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“EmbeddedContentXML”,typeof(MISMOXML),Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“MIMETypeIdentifier”,typeof(MISMOIdentifier),Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“ObjectCreatedDatetime”,typeof(MISMODatetime),Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“ObjectDescription”,Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“ObjectEncodingType”,typeof(ObjectEncodingEnum),Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“ObjectEncodingTypeOtherDescription”,Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“ObjectName”,Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“ObjectURI”,typeof(string),DataType = “anyURI”,Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“OriginalCreatorDigestValue”,typeof(MISMOValue),Order = 0)] [System.Xml.Serialization.XmlElementAttribute(“REFERENCE”,typeof(REFERENCE),Order = 0)] [System.Xml.Serialization.XmlChoiceIdentifierAttribute(“ItemsElementName”)] public List<object> Items { get { return this.itemsField; } set { this.itemsField = value; } } [System.Xml.Serialization.XmlElementAttribute(“ItemsElementName”,Order = 1)] [System.Xml.Serialization.XmlIgnoreAttribute()] public List<ItemsChoiceType> ItemsElementName { get { return this.itemsElementNameField; } set { this.itemsElementNameField = value; } } [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified,Namespace = “http://www.w3.org/1999/xlink”)] public MISMOresourceLink type { get { return this.typeField; } set { this.typeField = value; } } [System.Xml.Serialization.XmlIgnoreAttribute()] public bool typeSpecified { get { return this.typeFieldSpecified; } set { this.typeFieldSpecified = value; } } [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified,Namespace = “http://www.w3.org/1999/xlink”)] public string role { get { return this.roleField; } set { this.roleField = value; } } [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified,Namespace = “http://www.w3.org/1999/xlink”)] public string title { get { return this.titleField; } set { this.titleField = value; } } [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified,Namespace = “http://www.w3.org/1999/xlink”,DataType = “NMTOKEN”)] public string label { get { return this.labelField; } set { this.labelField = value; } } [System.Xml.Serialization.XmlAttributeAttribute(DataType = “integer”)] public string SequenceNumber { get { return this.sequenceNumberField; } set { this.sequenceNumberField = value; } } private static System.Xml.Serialization.XmlSerializer Serializer { get { if ((serializer == null)) { serializer = new System.Xml.Serialization.XmlSerializer(typeof(FOREIGN_OBJECT)); } return serializer; } } #region Serialize/Deserialize /// <summary> /// Serializes current FOREIGN_OBJECT object into an XML document /// </summary> /// <returns>string XML value</returns> public virtual string Serialize(System.Text.Encoding encoding) { System.IO.StreamReader streamReader = null; System.IO.MemoryStream memoryStream = null; try { memoryStream = new System.IO.MemoryStream(); System.Xml.XmlWriterSettings xmlWriterSettings = new System.Xml.XmlWriterSettings(); xmlWriterSettings.Encoding = encoding; System.Xml.XmlWriter xmlWriter = XmlWriter.Create(memoryStream,xmlWriterSettings); Serializer.Serialize(xmlWriter,this); memoryStream.Seek(0,System.IO.SeekOrigin.Begin); streamReader = new System.IO.StreamReader(memoryStream); return streamReader.ReadToEnd(); } finally { if ((streamReader != null)) { streamReader.Dispose(); } if ((memoryStream != null)) { memoryStream.Dispose(); } } } public virtual string Serialize() { return Serialize(Encoding.UTF8); } /// <summary> /// Deserializes workflow markup into an FOREIGN_OBJECT object /// </summary> /// <param name=”xml”>string workflow markup to deserialize</param> /// <param name=”obj”>Output FOREIGN_OBJECT object</param> /// <param name=”exception”>output Exception value if deserialize Failed</param> /// <returns>true if this XmlSerializer can deserialize the object; otherwise,false</returns> public static bool Deserialize(string xml,out FOREIGN_OBJECT obj,out System.Exception exception) { exception = null; obj = default(FOREIGN_OBJECT); try { obj = Deserialize(xml); return true; } catch (System.Exception ex) { exception = ex; return false; } } public static bool Deserialize(string xml,out FOREIGN_OBJECT obj) { System.Exception exception = null; return Deserialize(xml,out obj,out exception); } public static FOREIGN_OBJECT Deserialize(string xml) { System.IO.StringReader stringReader = null; try { stringReader = new System.IO.StringReader(xml); return ((FOREIGN_OBJECT)(Serializer.Deserialize(System.Xml.XmlReader.Create(stringReader)))); } finally { if ((stringReader != null)) { stringReader.Dispose(); } } } /// <summary> /// Serializes current FOREIGN_OBJECT object into file /// </summary> /// <param name=”fileName”>full path of outupt xml file</param> /// <param name=”exception”>output Exception value if Failed</param> /// <returns>true if can serialize and save into file; otherwise,false</returns> public virtual bool SaveToFile(string fileName,System.Text.Encoding encoding,out System.Exception exception) { exception = null; try { SaveToFile(fileName,encoding); return true; } catch (System.Exception e) { exception = e; return false; } } public virtual bool SaveToFile(string fileName,out System.Exception exception) { return SaveToFile(fileName,Encoding.UTF8,out exception); } public virtual void SaveToFile(string fileName) { SaveToFile(fileName,Encoding.UTF8); } public virtual void SaveToFile(string fileName,System.Text.Encoding encoding) { System.IO.StreamWriter streamWriter = null; try { string xmlString = Serialize(encoding); streamWriter = new System.IO.StreamWriter(fileName,false,Encoding.UTF8); streamWriter.WriteLine(xmlString); streamWriter.Close(); } finally { if ((streamWriter != null)) { streamWriter.Dispose(); } } } /// <summary> /// Deserializes xml markup from file into an FOREIGN_OBJECT object /// </summary> /// <param name=”fileName”>string xml file to load and deserialize</param> /// <param name=”obj”>Output FOREIGN_OBJECT object</param> /// <param name=”exception”>output Exception value if deserialize Failed</param> /// <returns>true if this XmlSerializer can deserialize the object; otherwise,false</returns> public static bool LoadFromFile(string fileName,out System.Exception exception) { exception = null; obj = default(FOREIGN_OBJECT); try { obj = LoadFromFile(fileName,encoding); return true; } catch (System.Exception ex) { exception = ex; return false; } } public static bool LoadFromFile(string fileName,out System.Exception exception) { return LoadFromFile(fileName,out exception); } public static bool LoadFromFile(string fileName,out FOREIGN_OBJECT obj) { System.Exception exception = null; return LoadFromFile(fileName,out exception); } public static FOREIGN_OBJECT LoadFromFile(string fileName) { return LoadFromFile(fileName,Encoding.UTF8); } public static FOREIGN_OBJECT LoadFromFile(string fileName,System.Text.Encoding encoding) { System.IO.FileStream file = null; System.IO.StreamReader sr = null; try { file = new System.IO.FileStream(fileName,FileMode.Open,FileAccess.Read); sr = new System.IO.StreamReader(file,encoding); string xmlString = sr.ReadToEnd(); sr.Close(); file.Close(); return Deserialize(xmlString); } finally { if ((file != null)) { file.Dispose(); } if ((sr != null)) { sr.Dispose(); } } } #endregion #region Clone method /// <summary> /// Create a clone of this FOREIGN_OBJECT object /// </summary> public virtual FOREIGN_OBJECT Clone() { return ((FOREIGN_OBJECT)(this.MemberwiseClone())); } #endregion}解决方法 仅当ChoiceIdentifier是一个数组而不是泛型列表时,才支持XmlChoiceIdentifierAttribute中的多个元素. [System.Xml.Serialization.XmlElementAttribute(“ItemsElementName”,Order = 1)][System.Xml.Serialization.XmlIgnoreAttribute()]public ItemsChoiceType[] ItemsElementName{ // …}

该错误令人困惑,因为它假设Items是类似数组(A列表)并且您的选择标识符不是数组,您在选择标识符的类型之前错过了数组限定符.但事实并非如此,所以这个建议完全是误导性的.

注意:理论上看代码(来自微软源服务器)项不需要是数组……实际上,临时序列化类的生成完全爆炸,因为List.Length不是公共的(它是显式实现的)