Procédure pas à pas : sérialiser des proxys POCO avec WCF (Entity Framework)
Le type de proxy POCO ne peut pas être directement sérialisé ou désérialisé par Windows Communication Foundation (WCF), parce que le moteur de sérialisation DataContractSerializer peut sérialiser et désérialiser uniquement des types connus. Le type proxy est inconnu. Pour plus d'informations, consultez la section Sérialisation de proxys POCO dans la rubrique Utilisation d'entités POCO (Entity Framework). Pour sérialiser des proxys POCO en tant qu'entités POCO, utilisez la classe ProxyDataContractResolver pour mapper les types de proxy aux types POCO pendant la sérialisation.
L'exemple dans cette rubrique explique comment indiquer au DataContractSerializer d'utiliser la classe ProxyDataContractResolver dans les opérations de service en définissant une classe d'attributs qui s'appliquera aux opérations de service qui utilisent en interne le ProxyDataContractResolver pour mapper les types de proxy aux types POCO. Il indique également comment associer la classe d'attributs aux méthodes qui font partie d'un contrat de service dans votre application WCF.
Les exemples de cette rubrique utilisent les classes POCO définies dans Procédure : définir des entités POCO (Entity Framework) et un modèle de données basé sur AdventureWorks défini dans Procédure : personnaliser des fichiers de modèle et de mappage pour utiliser des objets personnalisés (Entity Framework).
Pour créer le projet Bibliothèque de classes contenant des classes POCO
Créez un nouveau projet de bibliothèque de classes nommé POCOAdventureWorksModel.
Supprimez le fichier de code source par défaut qui a été ajouté au projet.
Ajoutez un modèle vide nommé AdventureWorksModel. Pour créer un modèle vide, consultez la section Pour créer un fichier .edmx vide dans la rubrique How to: Create a New .edmx File. Modifiez le modèle en suivant les étapes décrites dans la rubrique Fichier AdventureWorks.edmx personnalisé (Entity Framework).
Désactivez la génération de code pour le fichier .edmx. Ouvrez le fichier .edmx dans ADO.NET Entity Data Model Designer (Concepteur d'entités). Cliquez avec le bouton droit sur l'aire du concepteur, puis sélectionnez Propriétés. Dans la fenêtre Propriétés, sélectionnez la propriété Stratégie de génération de code et sélectionnez None. Si la fenêtre Propriétés n'est pas visible, appuyez sur F4.
Ajoutez le fichier app.config à votre projet de bibliothèque de classes. Cliquez avec le bouton droit sur POCOAdventureWorksModel, pointez sur Ajouter, puis cliquez sur Nouvel élément.
Dans le dialogue Ajouter un nouvel élément, sélectionnez les modèles Général et sélectionnez Fichier de configuration de l'application. Copiez le code suivant entre des balises configuration dans le fichier de configuration de l'application. Modifiez la valeur Data Source si nécessaire.
<connectionStrings> <add name="AdventureWorksEntities" connectionString="metadata=res://*/AdventureWorksModel.csdl|res://*/AdventureWorksModel.ssdl|res://*/AdventureWorksModel.msl; provider=System.Data.SqlClient;provider connection string=" Data Source=(local);Initial Catalog=AdventureWorks; Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" /> </connectionStrings>
Ajoutez une référence à la bibliothèque System.Runtime.Serialization. Cette bibliothèque est nécessaire pour les attributs WCF DataContract et DataMember utilisés sur les types d'entité sérialisables.
Ajoutez une nouvelle classe à votre projet et nommez-la
POCOClasses
. Ajoutez au fichier le code dans Classes POCO sérialisables selon le modèle AdventureWorks. Cet élément contient le type d'entité et les définitions de contexte de l'objet.Compilez le projet.
Pour créer et configurer le projet WCF
Créez un projet WCF Service Application dans la même solution que le projet de bibliothèque de classes nommé POCOAdventureWorksService.
Ajoutez une référence à la bibliothèque System.Data.Entity.
Ajoutez une référence au projet POCOAdventureWorksModel, où le modèle est défini.
Ajoutez la chaîne de connexion au fichier .config pour permettre au runtime Entity Framework de trouver les métadonnées. Ouvrez le fichier app.config dans votre projet POCOAdventureWorksModel, copiez l'élément connectionStrings et ajoutez-le comme élément enfant de l'élément configuration du fichier Web.config.
Créez une nouvelle classe et nommez-la
ApplyDataContractResolverAttribute
.Ajoutez les espaces de noms suivants au début du fichier :
using System.Data.Objects; using System.ServiceModel.Description; using System.ServiceModel.Channels;
Remplacez le code généré pour la nouvelle classe par le code suivant :
public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior { public ApplyDataContractResolverAttribute() { } public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters) { } public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy) { DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>(); dataContractSerializerOperationBehavior.DataContractResolver = new ProxyDataContractResolver(); } public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch) { DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>(); dataContractSerializerOperationBehavior.DataContractResolver = new ProxyDataContractResolver(); } public void Validate(OperationDescription description) { // Do validation. } }
Ouvrez le fichier d'interface de service. Il est nommé IService1 par défaut.
Ajoutez l'espace de noms
POCOAdventureWorksModel
au début du fichier. C'est l'espace de noms où les types POCO sont définis.Remplacez le code qui définit le fichier de l'interface de service par le code suivant :
[ServiceContract] public interface IService1 { [OperationContract] [ApplyDataContractResolver] void UpdateOrder(Order updated); [OperationContract] [ApplyDataContractResolver] Order GetOrder(int OrderID); }
Ouvrez le code source du service. Par défaut, il est appelé Service1.srv.cs (ou .vb).
Ajoutez l'espace de noms
POCOAdventureWorksModel
au début du fichier.Remplacez le code qui définit la classe de service par le code suivant :
public class Service1 : IService1 { public void UpdateOrder(Order updated) { using (POCOAdventureWorksEntities context = new POCOAdventureWorksEntities()) { // Attach the original order to the context by querying the database. // Alternatively, you can require that the updated object be returned along with the original object from the client. // This means the client would need to clone the original object. Order original = context.Orders.SingleOrDefault(o => o.SalesOrderID == updated.SalesOrderID); // Apply changes to the order object. context.Orders.ApplyCurrentValues(updated); context.SaveChanges(); } } public Order GetOrder(int OrderID) { using (POCOAdventureWorksEntities context = new POCOAdventureWorksEntities()) { // You can disable the proxy creation // by setting context.ContextOptions.ProxyCreationEnabled to false context.ContextOptions.LazyLoadingEnabled = false; // The order was created as a POCO proxy object. // But it will be recieved on the client as a pure POCO. Order order = context.Orders.SingleOrDefault(o => o.SalesOrderID == OrderID); return order; } } }
Compilez le projet.
Pour tester le service
Créez une application console. Tapez POCOAdventureWorksTest comme nom de projet.
Ajoutez au projet une référence à POCOAdventureWorksModel.
Ajoutez une référence au service POCOAdventureWorksService. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le dossier de la référence, puis cliquez sur Ajouter la référence de service.
Ouvrez le fichier app.config et ajoutez la chaîne de connexion au fichier. Ouvrez le fichier app.config de l'élément POCOAdventureWorksModel, copiez l'élément connectionStrings et ajoutez-le comme élément enfant de l'élément configuration du fichier Web.config.
Ouvrez le fichier qui contient la fonction principale.
Ajoutez les espaces de noms suivants, où le service et les types POCO sont définis, au début du fichier :
Service1Client client = new Service1Client(); int orderId = 43680; Order order = client.GetOrder(orderId); Console.WriteLine(order.DueDate); // Modify order. order.DueDate = DateTime.Now; // Update order in the database. client.UpdateOrder(order);
Remplacez le code par celui-ci : Notez que, bien que le service soit en mesure de sérialiser des proxys POCO, le client reçoit des objets POCO seuls.
Service1Client client = new Service1Client(); int orderId = 43680; Order order = client.GetOrder(orderId); Console.WriteLine(order.DueDate); // Modify order. order.DueDate = DateTime.Now; // Update order in the database. client.UpdateOrder(order);