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:
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 TodoService
rozszerza 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.
SoapService
Przykład:
TodoService
Tworzy wystąpienie wystąpienia na poziomie klasy- Tworzy kolekcję wywoływaną
Items
do przechowywaniaTodoItem
obiektów - Określa niestandardowy punkt końcowy dla właściwości opcjonalnej
Url
w obiekcieTodoService
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ć GetTodoItemsAsync
metodę , 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 TaskCompletionSource
element , rozpoczyna wywołanie asynchroniczne w metodzie RefreshDataAsync
i oczekuje na Task
podany przez TaskCompletionSource
element . 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.