7 votes

WCF - Instanciation d'un objet dans le constructeur de DataContract

J'ai deux classes comme ci-dessous :

[DataContract]
public class Address
{
   [DataMember]
   public string Line1
   [DataMember]   
   public string Line2
   [DataMember]
   public string City
   [DataMember]
   public string State
   [DataMember]
   public string Zip
}

[DataContract]
public class Customer
{
   public Customer()
   {
      CustomerAddress = new Address();
   }

   [DataMember]
   public string FirstName
   [DataMember]
   public string LastName
   [DataMember]
   public Address CustomerAddress
}

Que se passera-t-il si je génère un proxy de mon service qui utilise la classe Customer ? Si je comprends bien le concept, je pense que le constructeur de la classe Client ne sera pas appelé du côté client et que le comportement sera différent.

Comment puis-je me débarrasser de ce constructeur dans la classe Client tout en gardant la classe CustomerAddress propriété de type Address pour qu'il se comporte comme un objet DTO débile ?

Quelle est la ligne directrice générale ou les meilleures pratiques que les gens utilisent pour éviter cette situation ?

6voto

David Hoerster Points 18815

Si vous utilisez l'option par défaut DataContractSerializer pour sérialiser vos objets, alors, oui, votre constructeur n'est pas sérialisé, et toute logique que vous pouvez avoir dans celui-ci ne sera pas appelée par votre client lorsque l'objet est désérialisé.

En ce qui concerne votre question sur la suppression de la logique du constructeur et l'imbrication de l'image de l'utilisateur dans l'image de l'utilisateur. Address sera remplie, cela sera pris en charge par la classe DataContractSerializer . Si j'ai un code comme celui-ci :

Customer c = new Customer() { 
  FirstName = "David",
  LastName = "Hoerster",
  CustomerAddress = new Address() {
    Line1 = "1 Main Street",
    City = "Smallville",
    State = "AA",
    Zip = "12345"
  }
};

et ensuite le renvoyer à partir d'une méthode de service, qui Customer sera sérialisé correctement avec l'objet Address informations. Le proxy du client qui est généré connaîtra Address et sera capable de désérialiser le flux provenant de la méthode de service pour construire convenablement votre Customer objet. Votre Customer sera un DTO factice -- pas de logique, juste des propriétés.

Allez voir l'article d'Aaron Skonnard Article de MSDN sur WCF Serialization où il parle du DataContractSerializer.

1voto

CodingWithSpike Points 17720

Si vous générer le client (en utilisant svcutil ou "add service reference"), alors le DataContract généré ressemblera à ceci :

[DataContract]
public class Customer
{
   // empty default constructor
   public Customer()
   {
   }

   [DataMember]
   public string FirstName
   [DataMember]
   public string LastName
   [DataMember]
   public Address CustomerAddress
}

Les détails de votre mise en œuvre ne sont pas reportés. Tout ce qui est généré est ce qui va dans le WSDL, qui est juste le [DataMember] dans ce cas.

Je mentionne ceci parce que votre question initiale demande : " Que se passera-t-il si je génère un proxy ".


S'il s'agit d'un objet envoyé du serveur au client, vous pouvez toujours initialiser CustomerAddress avant de l'envoyer au client. En fait, si votre code original est sur le serveur, alors ce constructeur sera exécuté, et WCF sérialisera l'objet CustomerAddress. CustomerAddress et n'envoie jamais un null (à moins que vous ne le remettiez à null après le constructeur).

Si vous voulez faire en sorte que le client vous envoie toujours un message de type CustomerAddress alors vous pourriez :

  • ont le serveur vérifier la présence de null, comme if(x.CustomerAddress == null) x.CustomerAddress = new Address();
  • marquer le DataMember comme requis, alors le serveur retournera une erreur si le client n'a rien passé : [DataMember(IsRequired=true)] public Address CustomerAddress;

Sinon, je ne pense pas qu'il y ait un moyen de forcer le client WCF généré à initialiser ce champ pour vous.

0voto

xing Points 382

Il est préférable de définir toutes les classes de contrat de données dans un assemblage et de faire en sorte que le projet serveur et le projet client fassent référence à cet assemblage afin que le comportement d'initialisation puisse être partagé. Lors de la génération de la référence du service, vous pouvez demander au générateur de code d'utiliser les classes de contrat de données existantes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X