Udostępnij za pośrednictwem


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:

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 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 ObservableCollectionTodoWCFService.TodoItem , które jest następnie konwertowane na ListTodoItem 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ć TodoItemelementu , 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ć TodoItemelementu , 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ąć TodoItemobiektu , 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 localhostusł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.143IP . 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:

  1. 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
    
  2. 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 nazwie TodoWCFService. 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 jako binding. Dodaj następujący kod XML do bindings 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że bindings 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.

  3. 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 adres 10.0.2.2 w emulatorze jest kierowany do localhost 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.143to , 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.