web-dev-qa-db-fra.com

Exception de contrat de données. Ne peut pas être sérialisé

J'ai le WCF DataContract suivant:

[DataContract]
public class Occupant
{
    private string _Name;
    private string _Email;
    private string _Organization;
    private string _Badge;

    public Occupant(string name, string badge, string organization)
    {
        Name = name;
        Badge = badge;
        Organization = organization;
    }

    public Occupant(string name, string badge)
    {
        Value = name;
        Key = badge;
    }

    [DataMember]
    public string Key
    {
        get { return _Name; }
        set { _Name = value; }
    }

    [DataMember]
    public string Value
    {
        get { return _Badge; }
        set { _Badge = value; }
    }

    [DataMember]
    public string Name
    {
        get { return _Name; }
        set { _Name = value; }
    }

    [DataMember]
    public string Email
    {
        get { return _Email; }
        set { _Email = value; }
    }

    [DataMember]
    public string Organization
    {
        get { return _Organization; }
        set { _Organization = value; }
    }

    [DataMember]
    public string Badge
    {
        get { return _Badge; }
        set { _Badge = value; }
    }
}

Lorsque j'essaie d'accéder à ce service via un navigateur Web (il est hébergé sur IIS), le message d'erreur suivant s'affiche:

System.Runtime.Serialization.InvalidDataContractException: le type 'MyNamespace.Occupant' ne peut pas être sérialisé. Pensez à le marquer avec l'attribut DataContractAttribute et à tous les membres à sérialiser avec l'attribut DataMemberAttribute. Si le type est une collection, envisagez de le marquer avec CollectionDataContractAttribute.

Une de mes méthodes renvoie une List de type Occupant. Est-ce que cela en serait la cause?

48
Justin

Comme vous avez fourni un ou plusieurs constructeurs d'initialisation, vous devrez également ajouter un constructeur sans paramètre (par défaut).

c'est-à-dire que vous devez ajouter:

[DataContract]
public class Occupant
{
    // *** Needed only for Serialization
    public Occupant() {}
    ...

Cela est dû au fait que le constructeur default disparaît lorsque vous ajoutez un constructeur explicite.

[Le problème ne vient pas de la méthode retournant List<Occupant>, car les méthodes ne sont pas sérialisées.]]

98
StuartLC

Essayez d'ajouter un constructeur vide. Souvent, cela va déclencher le sérialiseur.

9
Rob Rodi

Vous avez besoin d'un constructeur par défaut sans paramètre. Je n'ai jamais l'intention d'utiliser réellement le mien. J'ai donc ajouté un résumé pour IntelliSense et levé une exception d'exécution pour l'empêcher de l'utiliser.

/// <summary>
/// parameterless default constructor only for serialization
/// </summary>
public MyClass() { throw new NotImplementedException("parameterless default constructor only for serialization"); }
5
Zack Peterson

Vous devez ajouter un constructeur de paramètre vide à votre classe datacontract

2
rada

Je suppose que ce serait parce que _Email n'est pas initialisé. Vous pouvez définir EmitDefaultValue à false et voir si cela aide:

[DataMember(EmitDefaultValue = false)]
public string Email
{
0
SwDevMan81

Lorsque vous n'avez AUCUN setter par défaut, procédez comme suit:

  1. Ajouter un constructeur sans paramètres;
  2. Et ajoutez ensemble privé au moins.

Cela m'aide.

0
Anton Semenov