Partager via


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 :

Exemple d’application

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 ListTodoItem 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.143IP. 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 :

  1. 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
    
  2. 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 nom TodoWCFService. 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 que binding. Ajoutez le code XML suivant à l’élément bindings , 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, votre bindings 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.

  3. 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’adresse 10.0.2.2 de l’émulateur est routée vers localhost l’ordinateur hôte via un proxy interne. Ces requêtes proxiées auront 127.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.