Partager via


Consommer un service web ASP.NET (ASMX)

ASMX permet de créer des services web qui envoient des messages à l’aide du protocole SOAP (Simple Object Access Protocol). SOAP est un protocole indépendant de la plateforme et indépendant du langage pour la création et l’accès aux services web. Les consommateurs d’un service ASMX n’ont pas besoin de savoir quoi que ce soit sur la plateforme, le modèle objet ou le langage de programmation utilisé pour implémenter le service. Ils doivent uniquement comprendre comment envoyer et recevoir des messages SOAP. Cet article montre comment utiliser un service SOAP ASMX à partir d’une Xamarin.Forms application.

Un message SOAP est un document XML contenant les éléments suivants :

  • Élément racine nommé Envelope qui identifie le document XML en tant que message SOAP.
  • Élément Header facultatif qui contient des informations spécifiques à l’application, telles que des données d’authentification. Si l’élément Header est présent, il doit s’agir du premier élément enfant de l’élément Envelope .
  • Élément Body requis qui contient le message SOAP destiné au destinataire.
  • Élément Fault facultatif utilisé pour indiquer les messages d’erreur. Si l’élément Fault est présent, il doit s’agir d’un élément enfant de l’élément Body .

SOAP peut fonctionner sur de nombreux protocoles de transport, notamment HTTP, SMTP, TCP et UDP. Toutefois, un service ASMX ne peut fonctionner que sur HTTP. La plateforme Xamarin prend en charge les implémentations SOAP 1.1 standard sur HTTP, ce qui inclut la prise en charge de la plupart des configurations de service ASMX standard.

Cet exemple inclut les applications mobiles qui s’exécutent sur des appareils physiques ou émulés et un service ASMX qui fournit des méthodes pour obtenir, ajouter, modifier et supprimer des données. Lorsque les applications mobiles sont exécutées, elles se connectent au service ASMX hébergé localement, comme 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 ASMX 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.

Créer le proxy TodoService

Une classe proxy, appelée TodoService, étend et fournit des SoapHttpClientProtocol méthodes de communication avec le service ASMX via HTTP. Le proxy est généré en ajoutant une référence web à chaque projet spécifique à la plateforme dans Visual Studio 2019 ou Visual Studio 2017. La référence web génère des méthodes et des événements pour chaque action définie dans le document WSDL (Web Services Description Language) du service.

Par exemple, l’action de GetTodoItems service génère une GetTodoItemsAsync méthode et un GetTodoItemsCompleted événement dans le proxy. La méthode générée a un type de retour void et appelle l’action GetTodoItems sur la classe parente SoapHttpClientProtocol . Lorsque la méthode appelée reçoit une réponse du service, elle déclenche l’événement GetTodoItemsCompleted et fournit les données de réponse dans la propriété de l’événement Result .

Créer l’implémentation ISoapService

Pour permettre au projet multiplateforme partagé d’utiliser le service, l’exemple définit l’interface ISoapService , qui suit le modèle de programmation asynchrone de tâche en C#. Chaque plateforme implémente le ISoapService proxy spécifique à la plateforme. L’exemple utilise des TaskCompletionSource objets pour exposer le proxy en tant qu’interface asynchrone de tâche. Vous trouverez plus d’informations sur l’utilisation TaskCompletionSource dans les implémentations de chaque type d’action dans les sections ci-dessous.

L’exemple SoapService:

  1. Instancie l’instance au niveau de la TodoService classe
  2. Crée une collection appelée Items pour stocker des TodoItem objets
  3. Spécifie un point de terminaison personnalisé pour la propriété facultative Url sur le TodoService
public class SoapService : ISoapService
{
    ASMXService.TodoService todoService;
    public List<TodoItem> Items { get; private set; } = new List<TodoItem>();

    public SoapService ()
    {
        todoService = new ASMXService.TodoService ();
        todoService.Url = Constants.SoapUrl;
        ...
    }
}

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 ToASMXServiceTodoItem méthode, comme illustré dans l’exemple de code suivant :

ASMXService.TodoItem ToASMXServiceTodoItem (TodoItem item)
{
    return new ASMXService.TodoItem {
        ID = item.ID,
        Name = item.Name,
        Notes = item.Notes,
        Done = item.Done
    };
}

Cette méthode crée une instance ASMService.TodoItem 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 FromASMXServiceTodoItem méthode, comme illustré dans l’exemple de code suivant :

static TodoItem FromASMXServiceTodoItem (ASMXService.TodoItem item)
{
    return new TodoItem {
        ID = item.ID,
        Name = item.Name,
        Notes = item.Notes,
        Done = item.Done
    };
}

Cette méthode récupère 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

L’interface ISoapService s’attend à ce que la RefreshDataAsync méthode retourne une Task collection d’éléments. Toutefois, la TodoService.GetTodoItemsAsync méthode retourne void. Pour satisfaire le modèle d’interface, vous devez appeler GetTodoItemsAsync, attendre que l’événement GetTodoItemsCompleted se déclenche et remplir la collection. Cela vous permet de renvoyer une collection valide à l’interface utilisateur.

L’exemple ci-dessous crée un nouvel TaskCompletionSourceappel asynchrone dans la RefreshDataAsync méthode et attend le Task fourni par le TaskCompletionSource. Lorsque le TodoService_GetTodoItemsCompleted gestionnaire d’événements est appelé, il remplit la Items collection et met à jour les TaskCompletionSourceéléments suivants :

public class SoapService : ISoapService
{
    TaskCompletionSource<bool> getRequestComplete = null;
    ...

    public SoapService()
    {
        ...
        todoService.GetTodoItemsCompleted += TodoService_GetTodoItemsCompleted;
    }

    public async Task<List<TodoItem>> RefreshDataAsync()
    {
        getRequestComplete = new TaskCompletionSource<bool>();
        todoService.GetTodoItemsAsync();
        await getRequestComplete.Task;
        return Items;
    }

    private void TodoService_GetTodoItemsCompleted(object sender, ASMXService.GetTodoItemsCompletedEventArgs e)
    {
        try
        {
            getRequestComplete = getRequestComplete ?? new TaskCompletionSource<bool>();

            Items = new List<TodoItem>();
            foreach (var item in e.Result)
            {
                Items.Add(FromASMXServiceTodoItem(item));
            }
            getRequestComplete?.TrySetResult(true);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(@"\t\tERROR {0}", ex.Message);
        }
    }

    ...
}

Pour plus d’informations, consultez Le modèle de programmation asynchrone et le TPL et la programmation asynchrone .NET Framework traditionnelle.

Créer ou modifier des données

Lorsque vous créez ou modifiez des données, vous devez implémenter la ISoapService.SaveTodoItemAsync méthode. Cette méthode détecte si l’élément TodoItem est nouveau ou mis à jour et appelle la méthode appropriée sur l’objet todoService . Les CreateTodoItemCompleted gestionnaires d’événements et EditTodoItemCompleted les gestionnaires d’événements doivent également être implémentés afin de savoir quand le todoService service ASMX a reçu une réponse (ces derniers peuvent être combinés en un seul gestionnaire, car ils effectuent la même opération). L’exemple suivant illustre les implémentations d’interface et de gestionnaire d’événements, ainsi que l’objet TaskCompletionSource utilisé pour fonctionner de manière asynchrone :

public class SoapService : ISoapService
{
    TaskCompletionSource<bool> saveRequestComplete = null;
    ...

    public SoapService()
    {
        ...
        todoService.CreateTodoItemCompleted += TodoService_SaveTodoItemCompleted;
        todoService.EditTodoItemCompleted += TodoService_SaveTodoItemCompleted;
    }

    public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
    {
        try
        {
            var todoItem = ToASMXServiceTodoItem(item);
            saveRequestComplete = new TaskCompletionSource<bool>();
            if (isNewItem)
            {
                todoService.CreateTodoItemAsync(todoItem);
            }
            else
            {
                todoService.EditTodoItemAsync(todoItem);
            }
            await saveRequestComplete.Task;
        }
        catch (SoapException se)
        {
            Debug.WriteLine("\t\t{0}", se.Message);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("\t\tERROR {0}", ex.Message);
        }
    }

    private void TodoService_SaveTodoItemCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        saveRequestComplete?.TrySetResult(true);
    }

    ...
}

Supprimer des données

La suppression de données nécessite une implémentation similaire. Définissez un gestionnaire d’événements, implémentez un TaskCompletionSourcegestionnaire d’événements et la ISoapService.DeleteTodoItemAsync méthode :

public class SoapService : ISoapService
{
    TaskCompletionSource<bool> deleteRequestComplete = null;
    ...

    public SoapService()
    {
        ...
        todoService.DeleteTodoItemCompleted += TodoService_DeleteTodoItemCompleted;
    }

    public async Task DeleteTodoItemAsync (string id)
    {
        try
        {
            deleteRequestComplete = new TaskCompletionSource<bool>();
            todoService.DeleteTodoItemAsync(id);
            await deleteRequestComplete.Task;
        }
        catch (SoapException se)
        {
            Debug.WriteLine("\t\t{0}", se.Message);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("\t\tERROR {0}", ex.Message);
        }
    }

    private void TodoService_DeleteTodoItemCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        deleteRequestComplete?.TrySetResult(true);
    }

    ...
}

Test du service web

Le test d’appareils physiques ou émulés avec un service hébergé localement nécessite une configuration IIS personnalisée, des adresses de point de terminaison et des règles de pare-feu à mettre en place. Pour plus d’informations sur la configuration de votre environnement à des fins de test, consultez la section Configurer l’accès à distance à IIS Express. La seule différence entre le test WCF et ASMX est le numéro de port de TodoService.