XmlSerializer(c#)报告反映类型时出错(类型= List <myclass>)

3

有人能帮忙吗?

我有一个将对象转换为数据集的方法。在这种情况下,对象是使用LIST的集合类的集合

以下是代码,但它会出现以下错误,位于XmlSerializer formatter= ...行:

错误如下:

反映类型“System.Collections.Generic.List`1[MyNameSpace.Model.InformeVehiculo]”时出错。

    public static DataSet TransformObjectToDataSet(System.Type type, object datos, string nombre)
    {
        XmlSerializer formatter = new XmlSerializer(type, "Coleccion" + nombre);
        MemoryStream buffer = new MemoryStream();
        formatter.Serialize(buffer, datos);
        buffer.Position = 0;
        DataSet dtsDatos = new DataSet(nombre);
        dtsDatos.ReadXml(buffer);

        return dtsDatos;
    }

我正在这样调用方法
   TransformObjectToDataSet(typeof(List<InformeVehiculo>), objColeccionInformeVehiculo, "ColeccionInformeVehiculo");

objColeccionInformeVehiculo是一个列表

我有点迷失了,有没有人知道它为什么失败了

编辑

在进一步查看InnerExeption后,最后一个显示如下内容

 {"Cannot serialize member MyNameSpace.Model.ObjectChangeTracker.ObjectsRemovedFromCollectionProperties of type MyNameSpace.Model.ObjectsRemovedFromCollectionProperties, because it implements IDictionary."}

实际上,在InformeVehiculo内部,我已经扩展它以持有对InformeContrato的引用(使用partial classes,这是由entity framework最初创建的模型)

InformeContrato是出现问题的地方。

这是我的类:

 public partial class InformeContrato : IObjectWithChangeTracker, INotifyPropertyChanged

与实体框架创建的部分类InformeVehiculo不同,InformeContrato不存在。因此,我手动创建了InformeContrato并插入了changeTracking相关内容。

在下面,我复制了一个由实体框架创建的MODEL中的区域。

    #region ChangeTracking

    protected virtual void OnPropertyChanged(String propertyName)
    {
        if (ChangeTracker.State != ObjectState.Added && ChangeTracker.State != ObjectState.Deleted)
        {
            ChangeTracker.State = ObjectState.Modified;
        }
        if (_propertyChanged != null)
        {
            _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected virtual void OnNavigationPropertyChanged(String propertyName)
    {
        if (_propertyChanged != null)
        {
            _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged { add { _propertyChanged += value; } remove { _propertyChanged -= value; } }
    private event PropertyChangedEventHandler _propertyChanged;
    private ObjectChangeTracker _changeTracker;

    //[DataMember]
    public ObjectChangeTracker ChangeTracker
    {
        get
        {
            if (_changeTracker == null)
            {
                _changeTracker = new ObjectChangeTracker();
                _changeTracker.ObjectStateChanging += HandleObjectStateChanging;
            }
            return _changeTracker;
        }
        set
        {
            if (_changeTracker != null)
            {
                _changeTracker.ObjectStateChanging -= HandleObjectStateChanging;
            }
            _changeTracker = value;
            if (_changeTracker != null)
            {
                _changeTracker.ObjectStateChanging += HandleObjectStateChanging;
            }
        }
    }

    private void HandleObjectStateChanging(object sender, ObjectStateChangingEventArgs e)
    {
        if (e.NewState == ObjectState.Deleted)
        {
            ClearNavigationProperties();
        }
    }

    protected bool IsDeserializing { get; private set; }

    [OnDeserializing]
    public void OnDeserializingMethod(StreamingContext context)
    {
        IsDeserializing = true;
    }

    [OnDeserialized]
    public void OnDeserializedMethod(StreamingContext context)
    {
        IsDeserializing = false;
        ChangeTracker.ChangeTrackingEnabled = true;
    }

    protected virtual void ClearNavigationProperties()
    {
        //AccesorioContrato.Clear();
    }

    #endregion

2
请显示您的异常的InnerException。 - wRAR
1
同意 - 你需要查看InnerException,如果必要的话,还要查看它的InnerException ,以此类推。通常情况下,它会非常明确地告诉你,例如类型是非公共的或缺少构造函数... 或者,给我们展示InformeVehiculo,我们也许可以自己重现这个问题。 - Marc Gravell
谢谢大家,我更新了问题。看起来它在ChangeTracking下失败,这是我最初从实体框架中复制的。 - mark smith
1个回答

3

IDictionary不可序列化,标准字典也是如此。您需要实现自定义字典类型以启用序列化。然后它就可以工作了。

XML序列化示例:

  [XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue>
    : Dictionary<TKey, TValue>, IXmlSerializable
{
    #region IXmlSerializable Members

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof (TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof (TValue));

        bool wasEmpty = reader.IsEmptyElement;
        reader.Read();

        if (wasEmpty)
            return;

        while (reader.NodeType != XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");

            reader.ReadStartElement("key");
            TKey key = (TKey) keySerializer.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadStartElement("value");
            TValue value = (TValue) valueSerializer.Deserialize(reader);
            reader.ReadEndElement();

            Add(key, value);

            reader.ReadEndElement();
            reader.MoveToContent();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof (TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof (TValue));

        foreach (TKey key in Keys)
        {
            writer.WriteStartElement("item");

            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();

            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }

    #endregion 
}

谢谢Jennifer,好的,在InformeContrato中,我可以在ChangeObject上方放置一个[NonSerializable]属性吗?这样行得通吗? - mark smith
是的。XmlIgnoreAttribute。您必须将属性放在实例上(即您说“持有引用”的位置),而不是类本身上:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlignoreattribute.aspx - Jennifer Zouak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接