Utiliser un service web Windows Communication Foundation (WCF)
WCF est l’infrastructure unifiée de Microsoft pour la création d’applications orientées services. Il permet aux développeurs de créer des applications distribuées sécurisées, fiables, traitées et interopérables. Cet article montre comment utiliser un service SOAP (Simple Object Access Protocol) WCF à partir d’une Xamarin.Forms application.
WCF décrit un service avec différents contrats, notamment :
- Contrats de données : définissez les structures de données qui constituent la base du contenu dans un message.
- Contrats de messages : composez des messages à partir de contrats de données existants.
- Contrats d’erreur : autorisez les erreurs SOAP personnalisées à spécifier.
- Contrats de service : spécifiez les opérations que les services prennent en charge et les messages nécessaires pour interagir avec chaque opération. Ils spécifient également tout comportement d’erreur personnalisé qui peut être associé aux opérations sur chaque service.
Il existe des différences entre les services web ASP.NET (ASMX) et WCF, mais WCF prend en charge les mêmes fonctionnalités que celles que fournit ASMX : messages SOAP sur HTTP. Pour plus d’informations sur la consommation d’un service ASMX, consultez Consommer ASP.NET services web (ASMX).
Important
La prise en charge de la plateforme Xamarin pour WCF est limitée aux messages SOAP codés en texte sur HTTP/HTTPS à l’aide de la BasicHttpBinding
classe.
La prise en charge de WCF nécessite l’utilisation d’outils uniquement disponibles dans un environnement Windows pour générer le proxy et héberger todoWCFService. La création et le test de l’application iOS nécessitent le déploiement de TodoWCFService sur un ordinateur Windows ou en tant que service web Azure.
Les applications natives Xamarin Forms partagent généralement du code avec une bibliothèque de classes .NET Standard. Toutefois, .NET Core ne prend actuellement pas en charge WCF afin que le projet partagé doit être une bibliothèque de classes portable héritée. Pour plus d’informations sur la prise en charge de WCF dans .NET Core, consultez Choix entre .NET Core et .NET Framework pour les applications serveur.
L’exemple de solution d’application inclut un service WCF qui peut être exécuté localement et est illustré dans la capture d’écran suivante :
Remarque
Dans iOS 9 et versions ultérieures, App Transport Security (ATS) applique des connexions sécurisées entre les ressources Internet (comme le serveur principal de l’application) et l’application, ce qui empêche la divulgation accidentelle d’informations sensibles. Étant donné que ATS est activé par défaut dans les applications créées pour iOS 9, toutes les connexions sont soumises aux exigences de sécurité ATS. Si les connexions ne répondent pas à ces exigences, elles échouent avec une exception.
ATS peut être supprimé s’il n’est pas possible d’utiliser le HTTPS
protocole et la communication sécurisée pour les ressources Internet. Pour ce faire, mettez à jour le fichier Info.plist de l’application. Pour plus d’informations, consultez App Transport Security.
Consommer le services web
Le service WCF fournit les opérations suivantes :
Operation | Description | Paramètres |
---|---|---|
GetTodoItems | Obtenir une liste de tâches | |
CreateTodoItem | Créer un élément de tâche | Un todoItem sérialisé XML |
EditTodoItem | Mettre à jour une tâche | Un todoItem sérialisé XML |
DeleteTodoItem | Supprimer une tâche | Un todoItem sérialisé XML |
Pour plus d’informations sur le modèle de données utilisé dans l’application, consultez Modélisation des données.
Un proxy doit être généré pour consommer un service WCF, ce qui permet à l’application de se connecter au service. Le proxy est construit en consommant des métadonnées de service qui définissent les méthodes et la configuration de service associée. Ces métadonnées sont exposées sous la forme d’un document WSDL (Web Services Description Language) généré par le service web. Le proxy peut être généré à l’aide du fournisseur de référence de service web Microsoft WCF dans Visual Studio 2017 pour ajouter une référence de service pour le service web à une bibliothèque .NET Standard. Une alternative à la création du proxy à l’aide du fournisseur de référence de service web Microsoft WCF dans Visual Studio 2017 consiste à utiliser l’outil Utilitaire de métadonnées ServiceModel (svcutil.exe). Pour plus d’informations, consultez l’outil Utilitaire de métadonnées ServiceModel (Svcutil.exe).
Les classes proxy générées fournissent des méthodes pour consommer les services web qui utilisent le modèle de conception APM (Asynchrone Programming Model). Dans ce modèle, une opération asynchrone est implémentée sous la forme de deux méthodes nommées BeginOperationName et EndOperationName, qui commencent et terminent l’opération asynchrone.
La méthode BeginOperationName commence l’opération asynchrone et retourne un objet qui implémente l’interface IAsyncResult
. Après avoir appelé BeginOperationName, une application peut continuer à exécuter des instructions sur le thread appelant, tandis que l’opération asynchrone a lieu sur un thread de pool de threads.
Pour chaque appel à BeginOperationName, l’application doit également appeler EndOperationName pour obtenir les résultats de l’opération. La valeur de retour de EndOperationName est le même type retourné par la méthode de service web synchrone. Par exemple, la EndGetTodoItems
méthode retourne une collection d’instances TodoItem
. La méthode EndOperationName inclut également un IAsyncResult
paramètre qui doit être défini sur l’instance retournée par l’appel correspondant à la méthode BeginOperationName .
La bibliothèque parallèle de tâches (TPL) peut simplifier le processus de consommation d’une paire de méthodes de début/fin APM en encapsulant les opérations asynchrones dans le même Task
objet. Cette encapsulation est fournie par plusieurs surcharges de la TaskFactory.FromAsync
méthode.
Pour plus d’informations sur APM, consultez Le modèle de programmation asynchrone et le TPL et la programmation asynchrone .NET Framework traditionnelle sur MSDN.
Créer l’objet TodoServiceClient
La classe proxy générée fournit la TodoServiceClient
classe, qui est utilisée pour communiquer avec le service WCF via HTTP. Il fournit des fonctionnalités permettant d’appeler des méthodes de service web en tant qu’opérations asynchrones à partir d’une instance de service identifiée par l’URI. Pour plus d’informations sur les opérations asynchrones, consultez Vue d’ensemble du support asynchrone.
L’instance TodoServiceClient
est déclarée au niveau de la classe afin que l’objet se trouve tant que l’application doit consommer le service WCF, comme indiqué dans l’exemple de code suivant :
public class SoapService : ISoapService
{
ITodoService todoService;
...
public SoapService ()
{
todoService = new TodoServiceClient (
new BasicHttpBinding (),
new EndpointAddress (Constants.SoapUrl));
}
...
}
L’instance TodoServiceClient
est configurée avec des informations de liaison et une adresse de point de terminaison. Une liaison est utilisée pour spécifier les détails du transport, de l’encodage et du protocole requis pour que les applications et les services communiquent entre eux. Spécifie BasicHttpBinding
que les messages SOAP codés en texte seront envoyés via le protocole de transport HTTP. La spécification d’une adresse de point de terminaison permet à l’application de se connecter à différentes instances du service WCF, à condition qu’il existe plusieurs instances publiées.
Pour plus d’informations sur la configuration de la référence de service, consultez Configuration de la référence de service.
Créer des objets de transfert de données
L’exemple d’application utilise la TodoItem
classe pour modéliser les données. Pour stocker un TodoItem
élément dans le service web, il doit d’abord être converti en type généré par TodoItem
le proxy. Cette opération est effectuée par la ToWCFServiceTodoItem
méthode, comme illustré dans l’exemple de code suivant :
TodoWCFService.TodoItem ToWCFServiceTodoItem (TodoItem item)
{
return new TodoWCFService.TodoItem
{
ID = item.ID,
Name = item.Name,
Notes = item.Notes,
Done = item.Done
};
}
Cette méthode crée simplement une nouvelle TodoWCFService.TodoItem
instance et définit chaque propriété sur la propriété identique de l’instance TodoItem
.
De même, lorsque les données sont récupérées à partir du service web, elles doivent être converties du type généré par TodoItem
le proxy en instance TodoItem
. Cette opération est effectuée avec la FromWCFServiceTodoItem
méthode, comme illustré dans l’exemple de code suivant :
static TodoItem FromWCFServiceTodoItem (TodoWCFService.TodoItem item)
{
return new TodoItem
{
ID = item.ID,
Name = item.Name,
Notes = item.Notes,
Done = item.Done
};
}
Cette méthode récupère simplement les données du type généré par TodoItem
le proxy et les définit dans l’instance nouvellement créée TodoItem
.
Récupérer des données
Les TodoServiceClient.BeginGetTodoItems
méthodes et TodoServiceClient.EndGetTodoItems
les méthodes permettent d’appeler l’opération GetTodoItems
fournie par le service web. Ces méthodes asynchrones sont encapsulées dans un Task
objet, comme illustré dans l’exemple de code suivant :
public async Task<List<TodoItem>> RefreshDataAsync ()
{
...
var todoItems = await Task.Factory.FromAsync <ObservableCollection<TodoWCFService.TodoItem>> (
todoService.BeginGetTodoItems,
todoService.EndGetTodoItems,
null,
TaskCreationOptions.None);
foreach (var item in todoItems)
{
Items.Add (FromWCFServiceTodoItem (item));
}
...
}
La Task.Factory.FromAsync
méthode crée une Task
méthode qui exécute la TodoServiceClient.EndGetTodoItems
méthode une fois la TodoServiceClient.BeginGetTodoItems
méthode terminée, avec le null
paramètre indiquant qu’aucune donnée n’est transmise au BeginGetTodoItems
délégué. Enfin, la valeur de l’énumération TaskCreationOptions
spécifie que le comportement par défaut pour la création et l’exécution des tâches doit être utilisé.
La TodoServiceClient.EndGetTodoItems
méthode retourne une ObservableCollection
instance TodoWCFService.TodoItem
, qui est ensuite convertie en instances List
TodoItem
pour l’affichage.
Créer un flux
Les TodoServiceClient.BeginCreateTodoItem
méthodes et TodoServiceClient.EndCreateTodoItem
les méthodes permettent d’appeler l’opération CreateTodoItem
fournie par le service web. Ces méthodes asynchrones sont encapsulées dans un Task
objet, comme illustré dans l’exemple de code suivant :
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
...
var todoItem = ToWCFServiceTodoItem (item);
...
await Task.Factory.FromAsync (
todoService.BeginCreateTodoItem,
todoService.EndCreateTodoItem,
todoItem,
TaskCreationOptions.None);
...
}
La Task.Factory.FromAsync
méthode crée une Task
méthode qui exécute la TodoServiceClient.EndCreateTodoItem
méthode une fois la TodoServiceClient.BeginCreateTodoItem
méthode terminée, avec le todoItem
paramètre étant les données passées dans le BeginCreateTodoItem
délégué pour spécifier la TodoItem
valeur à créer par le service web. Enfin, la valeur de l’énumération TaskCreationOptions
spécifie que le comportement par défaut pour la création et l’exécution des tâches doit être utilisé.
Le service web lève une FaultException
valeur si elle ne parvient pas à créer le TodoItem
, qui est géré par l’application.
Mettre à jour des données
Les TodoServiceClient.BeginEditTodoItem
méthodes et TodoServiceClient.EndEditTodoItem
les méthodes permettent d’appeler l’opération EditTodoItem
fournie par le service web. Ces méthodes asynchrones sont encapsulées dans un Task
objet, comme illustré dans l’exemple de code suivant :
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
...
var todoItem = ToWCFServiceTodoItem (item);
...
await Task.Factory.FromAsync (
todoService.BeginEditTodoItem,
todoService.EndEditTodoItem,
todoItem,
TaskCreationOptions.None);
...
}
La Task.Factory.FromAsync
méthode crée une Task
méthode qui exécute la TodoServiceClient.EndEditTodoItem
méthode une fois la TodoServiceClient.BeginCreateTodoItem
méthode terminée, avec le todoItem
paramètre étant les données passées dans le BeginEditTodoItem
délégué pour spécifier la TodoItem
mise à jour par le service web. Enfin, la valeur de l’énumération TaskCreationOptions
spécifie que le comportement par défaut pour la création et l’exécution des tâches doit être utilisé.
Le service web lève une FaultException
valeur si elle ne parvient pas à localiser ou à mettre à jour le TodoItem
, qui est géré par l’application.
Supprimer des données
Les TodoServiceClient.BeginDeleteTodoItem
méthodes et TodoServiceClient.EndDeleteTodoItem
les méthodes permettent d’appeler l’opération DeleteTodoItem
fournie par le service web. Ces méthodes asynchrones sont encapsulées dans un Task
objet, comme illustré dans l’exemple de code suivant :
public async Task DeleteTodoItemAsync (string id)
{
...
await Task.Factory.FromAsync (
todoService.BeginDeleteTodoItem,
todoService.EndDeleteTodoItem,
id,
TaskCreationOptions.None);
...
}
La Task.Factory.FromAsync
méthode crée une Task
méthode qui exécute la TodoServiceClient.EndDeleteTodoItem
méthode une fois la TodoServiceClient.BeginDeleteTodoItem
méthode terminée, avec le id
paramètre étant les données passées dans le BeginDeleteTodoItem
délégué pour spécifier la TodoItem
suppression par le service web. Enfin, la valeur de l’énumération TaskCreationOptions
spécifie que le comportement par défaut pour la création et l’exécution des tâches doit être utilisé.
Le service web lève une FaultException
exception si elle ne parvient pas à localiser ou à supprimer le TodoItem
, qui est géré par l’application.
Configurer l’accès à distance à IIS Express
Dans Visual Studio 2017 ou Visual Studio 2019, vous devez être en mesure de tester l’application UWP sur un PC sans configuration supplémentaire. Le test des clients Android et iOS peut nécessiter les étapes supplémentaires de cette section. Pour plus d’informations, consultez Connecter aux services web locaux à partir de simulateurs iOS et d’émulateurs Android.
Par défaut, IIS Express répond uniquement aux demandes à localhost
. Les appareils distants (tels qu’un appareil Android, un i Téléphone ou même un simulateur) n’ont pas accès à votre service WCF local. Vous devez connaître votre adresse IP de station de travail Windows 10 sur le réseau local. Dans le cadre de cet exemple, supposons que votre station de travail a l’adresse 192.168.1.143
IP. Les étapes suivantes expliquent comment configurer Windows 10 et IIS Express pour accepter les connexions à distance et se connecter au service à partir d’un appareil physique ou virtuel :
Ajoutez une exception au Pare-feu Windows. Vous devez ouvrir un port via le Pare-feu Windows que les applications de votre sous-réseau peuvent utiliser pour communiquer avec le service WCF. Créez une règle de trafic entrant ouvrant le port 49393 dans le pare-feu. À partir d’une invite de commandes d’administration, exécutez cette commande :
netsh advfirewall firewall add rule name="TodoWCFService" dir=in protocol=tcp localport=49393 profile=private remoteip=localsubnet action=allow
Configurez IIS Express pour accepter les connexions à distance. Vous pouvez configurer IIS Express en modifiant le fichier de configuration pour IIS Express sur [répertoire de solution].vs\config\applicationhost.config. Recherchez l’élément
site
avec le nomTodoWCFService
. Il doit ressembler au code XML suivant :<site name="TodoWCFService" id="2"> <application path="/" applicationPool="Clr4IntegratedAppPool"> <virtualDirectory path="/" physicalPath="C:\Users\tom\TodoWCF\TodoWCFService\TodoWCFService" /> </application> <bindings> <binding protocol="http" bindingInformation="*:49393:localhost" /> </bindings> </site>
Vous devez ajouter deux
binding
éléments pour ouvrir le port 49393 vers le trafic extérieur et l’émulateur Android. La liaison utilise un[IP address]:[port]:[hostname]
format qui spécifie la façon dont IIS Express répond aux demandes. Les requêtes externes ont des noms d’hôte qui doivent être spécifiés en tant quebinding
. Ajoutez le code XML suivant à l’élémentbindings
, en remplaçant l’adresse IP par votre propre adresse IP :<binding protocol="http" bindingInformation="*:49393:192.168.1.143" /> <binding protocol="http" bindingInformation="*:49393:127.0.0.1" />
Une fois que vos modifications de l’élément
bindings
doivent ressembler à ce qui suit :<site name="TodoWCFService" id="2"> <application path="/" applicationPool="Clr4IntegratedAppPool"> <virtualDirectory path="/" physicalPath="C:\Users\tom\TodoWCF\TodoWCFService\TodoWCFService" /> </application> <bindings> <binding protocol="http" bindingInformation="*:49393:localhost" /> <binding protocol="http" bindingInformation="*:49393:192.168.1.143" /> <binding protocol="http" bindingInformation="*:49393:127.0.0.1" /> </bindings> </site>
Important
Par défaut, IIS Express n’accepte pas les connexions à partir de sources externes pour des raisons de sécurité. Pour activer les connexions à partir d’appareils distants, vous devez exécuter IIS Express avec des autorisations Administration istratives. La méthode la plus simple consiste à exécuter Visual Studio 2017 avec des autorisations Administration istratives. Cela lance IIS Express avec des autorisations Administration istratives lors de l’exécution de TodoWCFService.
Avec ces étapes, vous devez être en mesure d’exécuter TodoWCFService et de vous connecter à partir d’autres appareils sur votre sous-réseau. Vous pouvez le tester en exécutant votre application et en visitant
http://localhost:49393/TodoService.svc
. Si vous recevez une erreur de requête incorrecte lors de la visite de cette URL, votrebindings
erreur peut être incorrecte dans la configuration IIS Express (la requête atteint IIS Express, mais est rejetée). Si vous obtenez une autre erreur, il se peut que votre application ne s’exécute pas ou que votre pare-feu soit configuré de manière incorrecte.Pour permettre à IIS Express de continuer à s’exécuter et à servir le service, désactivez l’option Modifier et continuer dans les débogueurs Web > propriétés > de projet.
Personnalisez les appareils de point de terminaison utilisés pour accéder au service. Cette étape implique la configuration de l’application cliente, en cours d’exécution sur un appareil physique ou émulé, pour accéder au service WCF.
L’émulateur Android utilise un proxy interne qui empêche l’émulateur d’accéder directement à l’adresse de
localhost
l’ordinateur hôte. Au lieu de cela, l’adresse10.0.2.2
de l’émulateur est routée verslocalhost
l’ordinateur hôte via un proxy interne. Ces requêtes proxiées auront127.0.0.1
comme nom d’hôte dans l’en-tête de requête, c’est pourquoi vous avez créé la liaison IIS Express pour ce nom d’hôte dans les étapes ci-dessus.Le simulateur iOS s’exécute sur un hôte de build Mac, même si vous utilisez le simulateur iOS distant pour Windows. Les demandes réseau du simulateur auront votre adresse IP de station de travail sur le réseau local comme nom d’hôte
192.168.1.143
(dans cet exemple, mais votre adresse IP réelle sera probablement différente). C’est pourquoi vous avez créé la liaison IIS Express pour ce nom d’hôte dans les étapes ci-dessus.Vérifiez que la
SoapUrl
propriété du fichier Constants.cs dans le projet TodoWCF (Portable) a des valeurs correctes pour votre réseau :public static string SoapUrl { get { var defaultUrl = "http://localhost:49393/TodoService.svc"; if (Device.RuntimePlatform == Device.Android) { defaultUrl = "http://10.0.2.2:49393/TodoService.svc"; } else if (Device.RuntimePlatform == Device.iOS) { defaultUrl = "http://192.168.1.143:49393/TodoService.svc"; } return defaultUrl; } }
Une fois que vous avez configuré l’Constants.cs avec les points de terminaison appropriés, vous devez être en mesure de vous connecter au TodoWCFService s’exécutant sur votre station de travail Windows 10 à partir d’appareils physiques ou virtuels.