Udostępnij za pośrednictwem


Korzystanie z usługi internetowej ASP.NET (ASMX)

Usługa ASMX umożliwia tworzenie usług internetowych, które wysyłają komunikaty przy użyciu protokołu SIMPLE Object Access Protocol (SOAP). Soap to niezależny od platformy i niezależny od języka protokół do tworzenia i uzyskiwania dostępu do usług internetowych. Konsumenci usługi ASMX nie muszą wiedzieć nic o platformie, modelu obiektów lub języku programowania używanym do implementowania usługi. Muszą tylko zrozumieć, jak wysyłać i odbierać komunikaty PROTOKOŁU SOAP. W tym artykule pokazano, jak korzystać z usługi ASMX SOAP z Xamarin.Forms poziomu aplikacji.

Komunikat PROTOKOŁU SOAP to dokument XML zawierający następujące elementy:

  • Element główny o nazwie Koperta identyfikujący dokument XML jako komunikat PROTOKOŁU SOAP.
  • Opcjonalny element Nagłówek zawierający informacje specyficzne dla aplikacji, takie jak dane uwierzytelniania. Jeśli element Nagłówek jest obecny, musi być pierwszym elementem podrzędnym elementu Koperta.
  • Wymagany element Treść zawierający komunikat SOAP przeznaczony dla adresata.
  • Opcjonalny element błędu używany do wskazywania komunikatów o błędach. Jeśli element Fault jest obecny, musi być elementem podrzędnym elementu Body.

Protokół SOAP może działać za pośrednictwem wielu protokołów transportowych, w tym HTTP, SMTP, TCP i UDP. Jednak usługa ASMX może działać tylko za pośrednictwem protokołu HTTP. Platforma Xamarin obsługuje standardowe implementacje protokołu SOAP 1.1 za pośrednictwem protokołu HTTP i obejmuje obsługę wielu standardowych konfiguracji usługi ASMX.

Ten przykład obejmuje aplikacje mobilne działające na urządzeniach fizycznych lub emulowanych oraz usługę ASMX, która udostępnia metody pobierania, dodawania, edytowania i usuwania danych. Po uruchomieniu aplikacji mobilnych łączą się z lokalnie hostowaną usługą ASMX, jak pokazano na poniższym zrzucie ekranu:

Przykładowa aplikacja

Uwaga

W systemie iOS 9 lub nowszym usługa App Transport Security (ATS) wymusza bezpieczne połączenia między zasobami internetowymi (takimi jak serwer zaplecza aplikacji) i aplikacją, co uniemożliwia przypadkowe ujawnienie poufnych informacji. Ponieważ usługa ATS jest domyślnie włączona w aplikacjach utworzonych dla systemu iOS 9, wszystkie połączenia będą objęte wymaganiami dotyczącymi zabezpieczeń usługi ATS. Jeśli połączenia nie spełniają tych wymagań, zakończy się niepowodzeniem z wyjątkiem. Usługę ATS można zrezygnować, jeśli nie można używać HTTPS protokołu i bezpiecznej komunikacji dla zasobów internetowych. Można to osiągnąć, aktualizując plik Info.plist aplikacji. Aby uzyskać więcej informacji, zobacz App Transport Security.

Korzystanie z usługi internetowej

Usługa ASMX udostępnia następujące operacje:

Działanie opis Parametry
GetTodoItems Pobieranie listy elementów do wykonania
CreateTodoItem Tworzenie nowego elementu do wykonania Kod XML serializowany todoItem
EditTodoItem Aktualizowanie elementu do wykonania Kod XML serializowany todoItem
DeleteTodoItem Usuwanie elementu do wykonania Kod XML serializowany todoItem

Aby uzyskać więcej informacji na temat modelu danych używanego w aplikacji, zobacz Modelowanie danych.

Tworzenie serwera proxy usługi TodoService

Klasa serwera proxy o nazwie TodoServicerozszerza SoapHttpClientProtocol i udostępnia metody komunikacji z usługą ASMX za pośrednictwem protokołu HTTP. Serwer proxy jest generowany przez dodanie odwołania internetowego do każdego projektu specyficznego dla platformy w programie Visual Studio 2019 lub Visual Studio 2017. Dokumentacja sieci Web generuje metody i zdarzenia dla każdej akcji zdefiniowanej w dokumencie Web Services Description Language (WSDL) usługi.

Na przykład GetTodoItems akcja usługi powoduje wystąpienie GetTodoItemsAsync metody i GetTodoItemsCompleted zdarzenia na serwerze proxy. Metoda wygenerowana ma typ zwracany void i wywołuje GetTodoItems akcję w klasie nadrzędnej SoapHttpClientProtocol . Gdy wywołana metoda odbiera odpowiedź z usługi, uruchamia GetTodoItemsCompleted zdarzenie i dostarcza dane odpowiedzi we właściwości zdarzenia Result .

Tworzenie implementacji usługi ISoapService

Aby umożliwić współużytkowany, międzyplatformowy projekt do pracy z usługą, przykład definiuje ISoapService interfejs, który jest zgodny z asynchronicznym modelem programowania Task w języku C#. Każda platforma implementuje ISoapService element , aby uwidocznić serwer proxy specyficzny dla platformy. W przykładzie użyto TaskCompletionSource obiektów do uwidocznienia serwera proxy jako interfejsu asynchronicznego zadania. Szczegółowe informacje na temat używania TaskCompletionSource znajdują się w implementacjach każdego typu akcji w poniższych sekcjach.

SoapServicePrzykład:

  1. TodoService Tworzy wystąpienie wystąpienia na poziomie klasy
  2. Tworzy kolekcję wywoływaną Items do przechowywania TodoItem obiektów
  3. Określa niestandardowy punkt końcowy dla właściwości opcjonalnej Url w obiekcie 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;
        ...
    }
}

Tworzenie obiektów transferu danych

Przykładowa aplikacja używa klasy do modelowania TodoItem danych. Aby zapisać TodoItem element w usłudze internetowej, należy go najpierw przekonwertować na typ wygenerowany TodoItem przez serwer proxy. Jest to realizowane przez metodę ToASMXServiceTodoItem , jak pokazano w poniższym przykładzie kodu:

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

Ta metoda tworzy nowe ASMService.TodoItem wystąpienie i ustawia każdą właściwość na identyczną właściwość z TodoItem wystąpienia.

Podobnie, gdy dane są pobierane z usługi internetowej, należy je przekonwertować z typu wygenerowanego TodoItem przez serwer proxy na TodoItem wystąpienie. Jest to realizowane za pomocą FromASMXServiceTodoItem metody , jak pokazano w poniższym przykładzie kodu:

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

Ta metoda pobiera dane z wygenerowanego TodoItem typu serwera proxy i ustawia je w nowo utworzonym TodoItem wystąpieniu.

Pobieranie danych

Interfejs ISoapService oczekuje RefreshDataAsync , że metoda zwróci Task element z kolekcją elementów. TodoService.GetTodoItemsAsync Jednak metoda zwraca wartość void. Aby spełnić wzorzec interfejsu, należy wywołać GetTodoItemsAsyncmetodę , poczekać na GetTodoItemsCompleted wyzwolenie zdarzenia i wypełnić kolekcję. Dzięki temu można zwrócić prawidłową kolekcję do interfejsu użytkownika.

Poniższy przykład tworzy nowy TaskCompletionSourceelement , rozpoczyna wywołanie asynchroniczne w metodzie RefreshDataAsync i oczekuje na Task podany przez TaskCompletionSourceelement . Gdy wywoływana TodoService_GetTodoItemsCompleted jest procedura obsługi zdarzeń, wypełnia Items kolekcję i aktualizuje element TaskCompletionSource:

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);
        }
    }

    ...
}

Aby uzyskać więcej informacji, zobacz Asynchroniczny model programowania oraz TPL i Tradycyjne programowanie asynchroniczne programu .NET Framework.

Tworzenie lub edytowanie danych

Podczas tworzenia lub edytowania danych należy zaimplementować metodę ISoapService.SaveTodoItemAsync . Ta metoda wykrywa, czy TodoItem element jest nowym, czy zaktualizowanym elementem i wywołuje odpowiednią metodę w todoService obiekcie. Programy CreateTodoItemCompleted obsługi zdarzeń i EditTodoItemCompleted powinny być również zaimplementowane, aby wiedzieć, kiedy todoService obiekt otrzymał odpowiedź z usługi ASMX (można je połączyć w jedną procedurę obsługi, ponieważ wykonują tę samą operację). W poniższym przykładzie pokazano implementacje interfejsu i procedury obsługi zdarzeń, a także TaskCompletionSource obiekt używany do asynchronicznego działania:

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);
    }

    ...
}

Usuwanie danych

Usuwanie danych wymaga podobnej implementacji. Zdefiniuj metodę TaskCompletionSource, zaimplementuj program obsługi zdarzeń i metodę ISoapService.DeleteTodoItemAsync :

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);
    }

    ...
}

Testowanie usługi internetowej

Testowanie urządzeń fizycznych lub emulowanych za pomocą lokalnie hostowanej usługi wymaga wdrożenia niestandardowych reguł konfiguracji usług IIS, adresów punktów końcowych i zapory. Aby uzyskać więcej informacji na temat konfigurowania środowiska do testowania, zobacz Konfigurowanie dostępu zdalnego do usług IIS Express. Jedyną różnicą między testowaniem usług WCF i ASMX jest numer portu usługi TodoService.