Korzystanie z usługi internetowej programu Windows Communication Foundation (WCF)
WCF to ujednolicona struktura firmy Microsoft służąca do tworzenia aplikacji zorientowanych na usługi. Umożliwia deweloperom tworzenie bezpiecznych, niezawodnych, transakcyjnych i współdziałalnych aplikacji rozproszonych. W tym artykule przedstawiono sposób korzystania z usługi WCF Simple Object Access Protocol (SOAP) z Xamarin.Forms aplikacji.
WCF opisuje usługę z różnymi kontraktami, w tym:
- Kontrakty danych — definiują struktury danych, które tworzą podstawę zawartości w komunikacie.
- Kontrakty komunikatów — tworzą komunikaty z istniejących kontraktów danych.
- Kontrakty błędów — umożliwiają określenie niestandardowych błędów protokołu SOAP.
- Kontrakty usług — określają operacje obsługiwane przez usługi i komunikaty wymagane do interakcji z każdą operacją. Określają one również wszelkie niestandardowe zachowanie błędów, które można skojarzyć z operacjami w każdej usłudze.
Istnieją różnice między usługami ASP.NET Web Services (ASMX) i WCF, ale program WCF obsługuje te same możliwości, które zapewnia ASMX — komunikaty PROTOKOŁU SOAP za pośrednictwem protokołu HTTP. Aby uzyskać więcej informacji na temat korzystania z usługi ASMX, zobacz Korzystanie z usług internetowych ASP.NET (ASMX).
Ważne
Obsługa platformy Xamarin dla usługi WCF jest ograniczona do komunikatów PROTOKOŁU SOAP zakodowanych tekstowo za pośrednictwem protokołu HTTP/HTTPS przy użyciu BasicHttpBinding
klasy .
Obsługa programu WCF wymaga użycia narzędzi dostępnych tylko w środowisku systemu Windows w celu wygenerowania serwera proxy i hostowania usługi TodoWCFService. Kompilowanie i testowanie aplikacji systemu iOS wymaga wdrożenia usługi TodoWCFService na komputerze z systemem Windows lub jako usługi internetowej platformy Azure.
Aplikacje natywne platformy Xamarin Forms zwykle udostępniają kod biblioteki klas platformy .NET Standard. Jednak platforma .NET Core nie obsługuje obecnie programu WCF, więc udostępniony projekt musi być starszą przenośną biblioteką klas. Aby uzyskać informacje o obsłudze programu WCF na platformie .NET Core, zobacz Wybieranie między platformami .NET Core i .NET Framework dla aplikacji serwerowych.
Przykładowe rozwiązanie aplikacji zawiera usługę WCF, którą można uruchomić lokalnie i przedstawiono 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 WCF 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.
Aby korzystać z usługi WCF, należy wygenerować serwer proxy , który umożliwia aplikacji łączenie się z usługą. Serwer proxy jest konstruowany przez używanie metadanych usługi, które definiują metody i skojarzoną konfigurację usługi. Te metadane są udostępniane w postaci dokumentu WSDL (Web Services Description Language), który jest generowany przez usługę internetową. Serwer proxy można utworzyć przy użyciu dostawcy odwołań usługi sieci Web programu Microsoft WCF w programie Visual Studio 2017, aby dodać odwołanie do usługi sieci Web do biblioteki .NET Standard. Alternatywą do utworzenia serwera proxy przy użyciu dostawcy dokumentacji usług sieci Web WCF w programie Visual Studio 2017 jest użycie narzędzia ServiceModel Metadata Tool (svcutil.exe). Aby uzyskać więcej informacji, zobacz ServiceModel Metadata Utility Tool (Svcutil.exe).
Wygenerowane klasy serwera proxy udostępniają metody korzystania z usług internetowych korzystających ze wzorca projektowego modelu programowania asynchronicznego (APM). W tym wzorcu operacja asynchroniczna jest implementowana jako dwie metody o nazwie BeginOperationName i EndOperationName, które rozpoczynają i kończą operację asynchroniczną.
Metoda BeginOperationName rozpoczyna operację asynchroniczną i zwraca obiekt implementujący IAsyncResult
interfejs. Po wywołaniu metody BeginOperationName aplikacja może kontynuować wykonywanie instrukcji w wątku wywołującym, podczas gdy operacja asynchroniczna odbywa się w wątku puli wątków.
Dla każdego wywołania beginOperationName aplikacja powinna również wywołać EndOperationName, aby uzyskać wyniki operacji. Zwracana wartość EndOperationName jest tym samym typem zwracanym przez synchroniczną metodę usługi internetowej. Na przykład EndGetTodoItems
metoda zwraca kolekcję TodoItem
wystąpień. Metoda EndOperationName zawiera IAsyncResult
również parametr, który powinien zostać ustawiony na wystąpienie zwrócone przez odpowiednie wywołanie metody BeginOperationName .
Biblioteka równoległa zadań (TPL) może uprościć proces korzystania z pary metod rozpoczęcia/zakończenia APM, hermetyzując operacje asynchroniczne w tym samym Task
obiekcie. Hermetyzacja jest dostarczana przez wiele przeciążeń TaskFactory.FromAsync
metody.
Aby uzyskać więcej informacji na temat APM, zobacz Asynchroniczny model programowania oraz TPL i Tradycyjne programowanie asynchroniczne programu .NET Framework w witrynie MSDN.
Tworzenie obiektu TodoServiceClient
Wygenerowana klasa serwera proxy udostępnia klasę TodoServiceClient
, która służy do komunikowania się z usługą WCF za pośrednictwem protokołu HTTP. Udostępnia ona funkcje wywoływania metod usługi internetowej jako operacji asynchronicznych z zidentyfikowanego wystąpienia usługi identyfikatora URI. Aby uzyskać więcej informacji na temat operacji asynchronicznych, zobacz Async Support Overview (Omówienie asynchronicznej pomocy technicznej).
TodoServiceClient
Wystąpienie jest deklarowane na poziomie klasy, tak aby obiekt mieścił się tak długo, jak aplikacja musi korzystać z usługi WCF, jak pokazano w poniższym przykładzie kodu:
public class SoapService : ISoapService
{
ITodoService todoService;
...
public SoapService ()
{
todoService = new TodoServiceClient (
new BasicHttpBinding (),
new EndpointAddress (Constants.SoapUrl));
}
...
}
Wystąpienie TodoServiceClient
jest konfigurowane z informacjami o powiązaniu i adresem punktu końcowego. Powiązanie służy do określania szczegółów transportu, kodowania i protokołu wymaganych dla aplikacji i usług do komunikowania się ze sobą. Określa BasicHttpBinding
, że komunikaty PROTOKOŁU SOAP zakodowane tekstowo będą wysyłane za pośrednictwem protokołu transportu HTTP. Określenie adresu punktu końcowego umożliwia aplikacji łączenie się z różnymi wystąpieniami usługi WCF, pod warunkiem, że istnieje wiele opublikowanych wystąpień.
Aby uzyskać więcej informacji na temat konfigurowania dokumentacji usługi, zobacz Konfigurowanie dokumentacji usługi.
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ę ToWCFServiceTodoItem
, jak pokazano w poniższym przykładzie kodu:
TodoWCFService.TodoItem ToWCFServiceTodoItem (TodoItem item)
{
return new TodoWCFService.TodoItem
{
ID = item.ID,
Name = item.Name,
Notes = item.Notes,
Done = item.Done
};
}
Ta metoda po prostu tworzy nowe TodoWCFService.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ą FromWCFServiceTodoItem
metody , jak pokazano w poniższym przykładzie kodu:
static TodoItem FromWCFServiceTodoItem (TodoWCFService.TodoItem item)
{
return new TodoItem
{
ID = item.ID,
Name = item.Name,
Notes = item.Notes,
Done = item.Done
};
}
Ta metoda po prostu pobiera dane z wygenerowanego TodoItem
typu serwera proxy i ustawia je w nowo utworzonym TodoItem
wystąpieniu.
Pobieranie danych
Metody TodoServiceClient.BeginGetTodoItems
i TodoServiceClient.EndGetTodoItems
służą do wywoływania GetTodoItems
operacji dostarczonej przez usługę internetową. Te metody asynchroniczne są hermetyzowane w Task
obiekcie, jak pokazano w poniższym przykładzie kodu:
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));
}
...
}
Metoda Task.Factory.FromAsync
tworzy metodę Task
, która wykonuje TodoServiceClient.EndGetTodoItems
metodę po zakończeniu TodoServiceClient.BeginGetTodoItems
metody z parametrem null
wskazującym, że żadne dane nie są przekazywane do delegata BeginGetTodoItems
. Na koniec wartość TaskCreationOptions
wyliczenia określa, że należy użyć domyślnego zachowania podczas tworzenia i wykonywania zadań.
Metoda TodoServiceClient.EndGetTodoItems
zwraca wystąpienie ObservableCollection
TodoWCFService.TodoItem
, które jest następnie konwertowane na List
TodoItem
wystąpienia do wyświetlania.
Tworzenie danych
Metody TodoServiceClient.BeginCreateTodoItem
i TodoServiceClient.EndCreateTodoItem
służą do wywoływania CreateTodoItem
operacji dostarczonej przez usługę internetową. Te metody asynchroniczne są hermetyzowane w Task
obiekcie, jak pokazano w poniższym przykładzie kodu:
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
...
var todoItem = ToWCFServiceTodoItem (item);
...
await Task.Factory.FromAsync (
todoService.BeginCreateTodoItem,
todoService.EndCreateTodoItem,
todoItem,
TaskCreationOptions.None);
...
}
Metoda Task.Factory.FromAsync
tworzy metodę Task
, która wykonuje TodoServiceClient.EndCreateTodoItem
metodę po zakończeniu TodoServiceClient.BeginCreateTodoItem
metody, a todoItem
parametr jest danymi przekazywanymi do BeginCreateTodoItem
delegata w celu określenia wartości TodoItem
, która ma zostać utworzona przez usługę internetową. Na koniec wartość TaskCreationOptions
wyliczenia określa, że należy użyć domyślnego zachowania podczas tworzenia i wykonywania zadań.
Usługa internetowa zgłasza FaultException
błąd, jeśli nie można utworzyć TodoItem
elementu , który jest obsługiwany przez aplikację.
Aktualizowanie danych
Metody TodoServiceClient.BeginEditTodoItem
i TodoServiceClient.EndEditTodoItem
służą do wywoływania EditTodoItem
operacji dostarczonej przez usługę internetową. Te metody asynchroniczne są hermetyzowane w Task
obiekcie, jak pokazano w poniższym przykładzie kodu:
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
...
var todoItem = ToWCFServiceTodoItem (item);
...
await Task.Factory.FromAsync (
todoService.BeginEditTodoItem,
todoService.EndEditTodoItem,
todoItem,
TaskCreationOptions.None);
...
}
Metoda Task.Factory.FromAsync
tworzy metodę Task
, która wykonuje TodoServiceClient.EndEditTodoItem
metodę po zakończeniu TodoServiceClient.BeginCreateTodoItem
metody, a todoItem
parametr jest danymi przekazywanymi do BeginEditTodoItem
delegata w celu określenia wartości TodoItem
, która ma zostać zaktualizowana przez usługę internetową. Na koniec wartość TaskCreationOptions
wyliczenia określa, że należy użyć domyślnego zachowania podczas tworzenia i wykonywania zadań.
Usługa internetowa zgłasza FaultException
błąd, jeśli nie można zlokalizować lub zaktualizować TodoItem
elementu , który jest obsługiwany przez aplikację.
Usuwanie danych
Metody TodoServiceClient.BeginDeleteTodoItem
i TodoServiceClient.EndDeleteTodoItem
służą do wywoływania DeleteTodoItem
operacji dostarczonej przez usługę internetową. Te metody asynchroniczne są hermetyzowane w Task
obiekcie, jak pokazano w poniższym przykładzie kodu:
public async Task DeleteTodoItemAsync (string id)
{
...
await Task.Factory.FromAsync (
todoService.BeginDeleteTodoItem,
todoService.EndDeleteTodoItem,
id,
TaskCreationOptions.None);
...
}
Metoda Task.Factory.FromAsync
tworzy metodę Task
, która wykonuje TodoServiceClient.EndDeleteTodoItem
metodę po zakończeniu TodoServiceClient.BeginDeleteTodoItem
metody, a id
parametr jest danymi przekazywanymi do BeginDeleteTodoItem
delegata w celu określenia wartości TodoItem
, która ma zostać usunięta przez usługę internetową. Na koniec wartość TaskCreationOptions
wyliczenia określa, że należy użyć domyślnego zachowania podczas tworzenia i wykonywania zadań.
Usługa internetowa zgłasza FaultException
błąd, jeśli nie można zlokalizować lub usunąć TodoItem
obiektu , który jest obsługiwany przez aplikację.
Konfigurowanie dostępu zdalnego do usług IIS Express
W programie Visual Studio 2017 lub Visual Studio 2019 powinno być możliwe przetestowanie aplikacji platformy UWP na komputerze bez dodatkowej konfiguracji. Testowanie klientów systemów Android i iOS może wymagać dodatkowych kroków w tej sekcji. Aby uzyskać więcej informacji, zobacz Połączenie do lokalnych usług sieci Web z symulatorów systemu iOS i emulatorów systemu Android.
Domyślnie usługa IIS Express będzie odpowiadać tylko na żądania do localhost
usługi . Urządzenia zdalne (takie jak urządzenie z systemem Android, i Telefon lub nawet symulator) nie będą miały dostępu do lokalnej usługi WCF. Musisz znać adres IP stacji roboczej z systemem Windows 10 w sieci lokalnej. W tym przykładzie przyjęto założenie, że stacja robocza ma adres 192.168.1.143
IP . W poniższych krokach opisano sposób konfigurowania systemów Windows 10 i IIS Express w celu akceptowania połączeń zdalnych i nawiązywania połączenia z usługą z urządzenia fizycznego lub wirtualnego:
Dodaj wyjątek do Zapory systemu Windows. Musisz otworzyć port za pośrednictwem Zapory systemu Windows, który aplikacje w podsieci mogą używać do komunikowania się z usługą WCF. Utwórz regułę ruchu przychodzącego otwierającą port 49393 w zaporze. W wierszu polecenia administracyjnego uruchom następujące polecenie:
netsh advfirewall firewall add rule name="TodoWCFService" dir=in protocol=tcp localport=49393 profile=private remoteip=localsubnet action=allow
Skonfiguruj usługę IIS Express, aby akceptowała połączenia zdalne. Usług IIS Express można skonfigurować, edytując plik konfiguracji dla usług IIS Express pod adresem [katalog rozwiązania].vs\config\applicationhost.config.
site
Znajdź element o nazwieTodoWCFService
. Powinien on wyglądać podobnie do następującego kodu XML:<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>
Należy dodać dwa
binding
elementy, aby otworzyć port 49393 do ruchu zewnętrznego i emulatora systemu Android. Powiązanie używa formatu określającego[IP address]:[port]:[hostname]
, w jaki sposób usługa IIS Express będzie odpowiadać na żądania. Żądania zewnętrzne będą miały nazwy hostów, które muszą być określone jakobinding
. Dodaj następujący kod XML dobindings
elementu, zastępując adres IP własnym adresem IP:<binding protocol="http" bindingInformation="*:49393:192.168.1.143" /> <binding protocol="http" bindingInformation="*:49393:127.0.0.1" />
Po wprowadzeniu zmian
bindings
element powinien wyglądać następująco:<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>
Ważne
Domyślnie usługa IIS Express nie będzie akceptować połączeń ze źródeł zewnętrznych ze względów bezpieczeństwa. Aby włączyć połączenia z urządzeń zdalnych, należy uruchomić usługę IIS Express z uprawnieniami Administracja istracyjnymi. Najprostszym sposobem wykonania tej czynności jest uruchomienie programu Visual Studio 2017 z uprawnieniami Administracja istracyjnymi. Spowoduje to uruchomienie programu IIS Express z uprawnieniami Administracja istracyjnymi podczas uruchamiania usługi TodoWCFService.
Po wykonaniu tych kroków powinno być możliwe uruchomienie usługi TodoWCFService i nawiązanie połączenia z innych urządzeń w podsieci. Możesz to przetestować, uruchamiając aplikację i odwiedzając stronę
http://localhost:49393/TodoService.svc
. Jeśli podczas odwiedzania tego adresu URL wystąpi błąd nieprawidłowego żądania , możebindings
to być nieprawidłowe w konfiguracji usług IIS Express (żądanie dociera do usługi IIS Express, ale jest odrzucane). Jeśli wystąpi inny błąd, może to oznaczać, że aplikacja nie jest uruchomiona lub zapora jest niepoprawnie skonfigurowana.Aby zezwolić usługom IIS Express na działanie i obsługę usługi, wyłącz opcję Edytuj i kontynuuj w debugerach sieci Web > właściwości > projektu.
Dostosuj urządzenia punktu końcowego używane do uzyskiwania dostępu do usługi. Ten krok obejmuje skonfigurowanie aplikacji klienckiej działającej na urządzeniu fizycznym lub emulowanym w celu uzyskania dostępu do usługi WCF.
Emulator systemu Android korzysta z wewnętrznego serwera proxy, który uniemożliwia emulatorowi bezpośredni dostęp do adresu maszyny
localhost
hosta. Zamiast tego adres10.0.2.2
w emulatorze jest kierowany dolocalhost
na maszynie hosta za pośrednictwem wewnętrznego serwera proxy. Te żądania proxied będą mieć127.0.0.1
jako nazwę hosta w nagłówku żądania, dlatego w powyższych krokach utworzono powiązanie usług IIS Express dla tej nazwy hosta.Symulator systemu iOS działa na hoście kompilacji na komputerze Mac, nawet jeśli używasz zdalnego symulatora systemu iOS dla systemu Windows. Żądania sieciowe z symulatora będą miały adres IP stacji roboczej w sieci lokalnej jako nazwę hosta (w tym przykładzie jest
192.168.1.143
to , ale rzeczywisty adres IP będzie prawdopodobnie inny). Dlatego w powyższych krokach utworzono powiązanie usług IIS Express dla tej nazwy hosta.Upewnij się,
SoapUrl
że właściwość w pliku Constants.cs w projekcie TodoWCF (Portable) ma wartości poprawne dla sieci: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; } }
Po skonfigurowaniu Constants.cs z odpowiednimi punktami końcowymi powinno być możliwe nawiązanie połączenia z usługą TodoWCFService uruchomioną na stacji roboczej z systemem Windows 10 z urządzeń fizycznych lub wirtualnych.