2010-03-30 16 views
2

Quelqu'un peut-il aider?Rapports XmlSerializer (C#) Une erreur est survenue lors de l'affichage du type (type = Liste <myclass>)

J'ai une méthode pour convertir un objet en un ensemble de données. Dans ce cas, l'objet est une collection (en utilisant LIST) aa classe collection

Voici le code, mais il des erreurs avec l'erreur suivante sur la ligne XmlSerializer = ... formatter

C'est l'erreur

Une erreur est survenue lors de l'affichage du type '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; 
    } 

J'appelle la méthode comme si

TransformObjectToDataSet(typeof(List<InformeVehiculo>), objColeccionInformeVehiculo, "ColeccionInformeVehiculo"); 

objColeccionInformeVehiculo est une liste

Je suis un peu perdu, personne ne sait pourquoi son échec

EDIT

Après avoir regardé fu complémen taires sur le InnerExeption, la dernière affiche les informations suivantes

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

En fait, à l'intérieur du InformeVehiculo je l'ai étendu à tenir une référence à InformeContracto (en utilisant des classes partielles, il est un modèle créé à l'origine par le cadre de l'entité)

InformeContrato est l'endroit où il échoue.

Cette ma classe

public partial class InformeContrato : IObjectWithChangeTracker, INotifyPropertyChanged 

InformeContrato n'existait pas la différence InformeVehiculo qui existait en tant que classe partielle créée par le cadre de l'entité. J'ai donc créé InformeContrato manuellement et j'ai inséré les trucs changeTracking ..

Plus bas, j'ai une région que j'ai copiée à partir d'un MODÈLE créé par Entity Framework.

#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

S'il vous plaît montrer InnerException de votre exception. – wRAR

+1

D'accord - vous devez regarder le 'InnerException', et si nécessaire le' InnerException' de cela, etc. Il indique généralement très clairement, par exemple que le type est non public ou manque d'un constructeur ... Sinon, montrez-nous 'InformeVehiculo' et nous pourrions être capables de le reproduire nous-mêmes. –

+0

Merci à tous, j'ai mis à jour la question. Il semble que ce soit sous ChangeTracking que j'ai initialement copié du framework d'entité. –

Répondre

2

IDictionary n'est pas sérialisable. Les dictionnaires standards ne le sont pas non plus. Vous devrez implémenter un type de dictionnaire personnalisé pour activer la sérialisation. Alors ça va marcher.

EX pour sérialisation 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 
} 
+0

Merci Jennifer, ok Y at-il un attribut que je peux placer au-dessus du ChangeObject dans InformeContrato [NonSerializable], cela fonctionnera-t-il? –

+0

Oui. XmlIgnoreAttribute. Vous devez placer l'attribut sur l'instance (c.-à-d.où vous dites "tenir une référence"), pas sur la classe elle-même: http://msdn.microsoft.com/fr-fr/library/system.xml.serialization.xmlignoreattribute.aspx –