Nutzen eines Wcf-Webdiensts (Windows Communication Foundation)

Beispiel herunterladen Das Beispiel herunterladen

WCF ist das einheitliche Framework von Microsoft zum Erstellen dienstorientierter Anwendungen. Es ermöglicht Entwicklern, sichere, zuverlässige, transaktionsfähige und interoperable verteilte Anwendungen zu erstellen. In diesem Artikel wird veranschaulicht, wie Sie einen WCF-SOAP-Dienst (Simple Object Access Protocol) aus einer Xamarin.Forms Anwendung nutzen.

WCF beschreibt einen Dienst mit einer Vielzahl verschiedener Verträge, einschließlich:

  • Datenverträge : Definieren Sie die Datenstrukturen, die die Grundlage für den Inhalt einer Nachricht bilden.
  • Nachrichtenverträge : Verfassen von Nachrichten aus vorhandenen Datenverträgen.
  • Fehlerverträge : Zulassen, dass benutzerdefinierte SOAP-Fehler angegeben werden.
  • Dienstverträge : Geben Sie die Vorgänge an, die von den Diensten unterstützt werden, und die Nachrichten, die für die Interaktion mit den einzelnen Vorgängen erforderlich sind. Sie geben auch ein beliebiges benutzerdefiniertes Fehlerverhalten an, das Vorgängen für jeden Dienst zugeordnet werden kann.

Es gibt Unterschiede zwischen ASP.NET Webdiensten (ASMX) und WCF, aber WCF unterstützt dieselben Funktionen wie ASMX – SOAP-Nachrichten über HTTP. Weitere Informationen zum Nutzen eines ASMX-Diensts finden Sie unter Nutzen ASP.NET Webdienste (ASMX).

Wichtig

Die Xamarin-Plattformunterstützung für WCF ist auf textcodierte SOAP-Nachrichten über HTTP/HTTPS unter Verwendung der BasicHttpBinding -Klasse beschränkt.

Wcf-Unterstützung erfordert die Verwendung von Tools, die nur in einer Windows-Umgebung verfügbar sind, um den Proxy zu generieren und den TodoWCFService zu hosten. Das Erstellen und Testen der iOS-App erfordert die Bereitstellung von TodoWCFService auf einem Windows-Computer oder als Azure-Webdienst.

Native Xamarin Forms-Apps teilen in der Regel Code mit einer .NET-Standardklassenbibliothek. .NET Core unterstützt WCF derzeit jedoch nicht, sodass es sich bei dem freigegebenen Projekt um eine Legacy-Portable-Klassenbibliothek handeln muss. Informationen zur WCF-Unterstützung in .NET Core finden Sie unter Auswählen zwischen .NET Core und .NET Framework für Server-Apps.

Die Beispielanwendungslösung enthält einen WCF-Dienst, der lokal ausgeführt werden kann, und ist im folgenden Screenshot dargestellt:

Beispielanwendung

Hinweis

In iOS 9 und höher erzwingt App Transport Security (ATS) sichere Verbindungen zwischen Internetressourcen (z. B. dem Back-End-Server der App) und der App, wodurch die versehentliche Offenlegung vertraulicher Informationen verhindert wird. Da ATS in Apps, die für iOS 9 erstellt wurden, standardmäßig aktiviert ist, unterliegen alle Verbindungen den ATS-Sicherheitsanforderungen. Wenn Verbindungen diese Anforderungen nicht erfüllen, schlagen sie mit einer Ausnahme fehl.

ATS kann abgemeldet werden, wenn es nicht möglich ist, das Protokoll und die HTTPS sichere Kommunikation für Internetressourcen zu verwenden. Dies kann durch Aktualisieren der Datei Info.plist der App erreicht werden. Weitere Informationen finden Sie unter App Transport Security.

Nutzen des Webdiensts

Der WCF-Dienst stellt die folgenden Vorgänge bereit:

Vorgang BESCHREIBUNG Parameter
GetTodoItems Abrufen einer Liste von To-Do-Elementen
CreateTodoItem Erstellen eines neuen To-Do-Elements Ein XML-serialisiertes TodoItem
EditTodoItem Aktualisieren eines To-Do-Elements Ein XML-serialisiertes TodoItem
DeleteTodoItem Löschen eines To-Do-Elements Ein XML-serialisiertes TodoItem

Weitere Informationen zum in der Anwendung verwendeten Datenmodell finden Sie unter Modellieren der Daten.

Ein Proxy muss generiert werden, um einen WCF-Dienst zu nutzen, sodass die Anwendung eine Verbindung mit dem Dienst herstellen kann. Der Proxy wird erstellt, indem Dienstmetadaten verwendet werden, die die Methoden und die zugehörige Dienstkonfiguration definieren. Diese Metadaten werden in Form eines WSDL-Dokuments (Web Services Description Language) verfügbar gemacht, das vom Webdienst generiert wird. Der Proxy kann mithilfe des Microsoft WCF Web Service Reference-Anbieters in Visual Studio 2017 erstellt werden, um einer .NET Standard-Bibliothek einen Dienstverweis für den Webdienst hinzuzufügen. Eine Alternative zum Erstellen des Proxys mit dem Microsoft WCF Web Service Reference-Anbieter in Visual Studio 2017 ist die Verwendung des ServiceModel Metadata Utility Tools (svcutil.exe). Weitere Informationen finden Sie unter ServiceModel Metadata Utility Tool (Svcutil.exe).

Die generierten Proxyklassen stellen Methoden zum Nutzen der Webdienste bereit, die das Entwurfsmuster Asynchrones Programmiermodell (APM) verwenden. In diesem Muster wird ein asynchroner Vorgang als zwei Methoden namens BeginOperationName und EndOperationName implementiert, die den asynchronen Vorgang beginnen und beenden.

Die BeginOperationName-Methode beginnt den asynchronen Vorgang und gibt ein Objekt zurück, das die IAsyncResult Schnittstelle implementiert. Nach dem Aufrufen von BeginOperationName kann eine Anwendung weiterhin Anweisungen für den aufrufenden Thread ausführen, während der asynchrone Vorgang in einem Threadpoolthread stattfindet.

Bei jedem Aufruf von BeginOperationName sollte die Anwendung auch EndOperationName aufrufen, um die Ergebnisse des Vorgangs abzurufen. Der Rückgabewert von EndOperationName ist derselbe Typ, der von der synchronen Webdienstmethode zurückgegeben wird. Die Methode gibt beispielsweise EndGetTodoItems eine Auflistung von TodoItem Instanzen zurück. Die EndOperationName-Methode enthält auch einen IAsyncResult Parameter, der auf den vom entsprechenden Aufruf der BeginOperationName-Methode zurückgegebenen instance festgelegt werden soll.

Die Task Parallel Library (TPL) kann die Verwendung eines APM-Start-End-Methodenpaars vereinfachen, indem die asynchronen Vorgänge im selben Task Objekt gekapselt werden. Diese Kapselung wird durch mehrere Überladungen der TaskFactory.FromAsync -Methode bereitgestellt.

Weitere Informationen zu APM finden Sie unter Asynchrones Programmiermodell und TPL und herkömmliche .NET Framework asynchrone Programmierung auf MSDN.

Erstellen des TodoServiceClient-Objekts

Die generierte Proxyklasse stellt die TodoServiceClient -Klasse bereit, die für die Kommunikation mit dem WCF-Dienst über HTTP verwendet wird. Es bietet Funktionen zum Aufrufen von Webdienstmethoden als asynchrone Vorgänge von einem URI identifizierten Dienst instance. Weitere Informationen zu asynchronen Vorgängen finden Sie unter Übersicht über den asynchronen Support.

Die TodoServiceClient instance wird auf Klassenebene deklariert, sodass das Objekt so lange lebt, wie die Anwendung den WCF-Dienst nutzen muss, wie im folgenden Codebeispiel gezeigt:

public class SoapService : ISoapService
{
  ITodoService todoService;
  ...

  public SoapService ()
  {
    todoService = new TodoServiceClient (
      new BasicHttpBinding (),
      new EndpointAddress (Constants.SoapUrl));
  }
  ...
}

Die TodoServiceClient instance wird mit Bindungsinformationen und einer Endpunktadresse konfiguriert. Eine Bindung wird verwendet, um die Transport-, Codierungs- und Protokolldetails anzugeben, die für die Kommunikation von Anwendungen und Diensten untereinander erforderlich sind. Gibt BasicHttpBinding an, dass textcodierte SOAP-Nachrichten über das HTTP-Transportprotokoll gesendet werden. Wenn Sie eine Endpunktadresse angeben, kann die Anwendung eine Verbindung mit verschiedenen Instanzen des WCF-Diensts herstellen, sofern mehrere veröffentlichte Instanzen vorhanden sind.

Weitere Informationen zum Konfigurieren der Dienstreferenz finden Sie unter Konfigurieren der Dienstreferenz.

Erstellen von Datenübertragungsobjekten

Die Beispielanwendung verwendet die TodoItem -Klasse zum Modellieren von Daten. Um ein TodoItem Element im Webdienst zu speichern, muss es zuerst in den proxygenerierten TodoItem Typ konvertiert werden. Dies wird durch die ToWCFServiceTodoItem -Methode erreicht, wie im folgenden Codebeispiel gezeigt:

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

Diese Methode erstellt einfach eine neue TodoWCFService.TodoItem instance und legt jede Eigenschaft auf die identische Eigenschaft aus dem TodoItem instance fest.

Auf ähnliche Weise müssen Daten beim Abrufen aus dem Webdienst vom proxygenerierten TodoItem Typ in eine TodoItem instance konvertiert werden. Dies wird mit der FromWCFServiceTodoItem -Methode erreicht, wie im folgenden Codebeispiel gezeigt:

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

Diese Methode ruft einfach die Daten aus dem proxygenerierten TodoItem Typ ab und legt sie im neu erstellten TodoItem instance fest.

Abrufen von Daten

Die TodoServiceClient.BeginGetTodoItems Methoden und TodoServiceClient.EndGetTodoItems werden verwendet, um den GetTodoItems vom Webdienst bereitgestellten Vorgang aufzurufen. Diese asynchronen Methoden werden in einem Task -Objekt gekapselt, wie im folgenden Codebeispiel gezeigt:

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

Die Task.Factory.FromAsync -Methode erstellt eine Task , die die TodoServiceClient.EndGetTodoItems Methode nach Abschluss der TodoServiceClient.BeginGetTodoItems Methode ausführt, wobei der null Parameter angibt, dass keine Daten an den BeginGetTodoItems Delegaten übergeben werden. Schließlich gibt der Wert der TaskCreationOptions Enumeration an, dass das Standardverhalten für die Erstellung und Ausführung von Aufgaben verwendet werden soll.

Die TodoServiceClient.EndGetTodoItems -Methode gibt eine ObservableCollection von TodoWCFService.TodoItem -Instanzen zurück, die dann zur Anzeige in eine List von TodoItem -Instanzen konvertiert wird.

Erstellen von Daten

Die TodoServiceClient.BeginCreateTodoItem Methoden und TodoServiceClient.EndCreateTodoItem werden verwendet, um den CreateTodoItem vom Webdienst bereitgestellten Vorgang aufzurufen. Diese asynchronen Methoden werden in einem Task -Objekt gekapselt, wie im folgenden Codebeispiel gezeigt:

public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
  ...
  var todoItem = ToWCFServiceTodoItem (item);
  ...
  await Task.Factory.FromAsync (
    todoService.BeginCreateTodoItem,
    todoService.EndCreateTodoItem,
    todoItem,
    TaskCreationOptions.None);
  ...
}

Die Task.Factory.FromAsync -Methode erstellt eine Task , die die TodoServiceClient.EndCreateTodoItem -Methode nach Abschluss der TodoServiceClient.BeginCreateTodoItem -Methode ausführt, wobei der todoItem Parameter die Daten sind, die an den BeginCreateTodoItem Delegaten übergeben werden, um den anzugeben, der TodoItem vom Webdienst erstellt werden soll. Schließlich gibt der Wert der TaskCreationOptions Enumeration an, dass das Standardverhalten für die Erstellung und Ausführung von Aufgaben verwendet werden soll.

Der Webdienst löst ein aus FaultException , wenn er die TodoItemnicht erstellen kann, die von der Anwendung verarbeitet wird.

Aktualisieren von Daten

Die TodoServiceClient.BeginEditTodoItem Methoden und TodoServiceClient.EndEditTodoItem werden verwendet, um den EditTodoItem vom Webdienst bereitgestellten Vorgang aufzurufen. Diese asynchronen Methoden werden in einem Task -Objekt gekapselt, wie im folgenden Codebeispiel gezeigt:

public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
  ...
  var todoItem = ToWCFServiceTodoItem (item);
  ...
  await Task.Factory.FromAsync (
    todoService.BeginEditTodoItem,
    todoService.EndEditTodoItem,
    todoItem,
    TaskCreationOptions.None);
  ...
}

Die Task.Factory.FromAsync -Methode erstellt eine Task , die die TodoServiceClient.EndEditTodoItem Methode nach Abschluss der TodoServiceClient.BeginCreateTodoItem Methode ausführt, wobei der todoItem Parameter die Daten sind, die an den BeginEditTodoItem Delegaten übergeben werden, um anzugeben, dass TodoItem vom Webdienst aktualisiert werden soll. Schließlich gibt der Wert der TaskCreationOptions Enumeration an, dass das Standardverhalten für die Erstellung und Ausführung von Aufgaben verwendet werden soll.

Der Webdienst löst einen aus FaultException , wenn er nicht suchen oder aktualisieren TodoItemkann, was von der Anwendung behandelt wird.

Löschen von Daten

Die TodoServiceClient.BeginDeleteTodoItem Methoden und TodoServiceClient.EndDeleteTodoItem werden verwendet, um den DeleteTodoItem vom Webdienst bereitgestellten Vorgang aufzurufen. Diese asynchronen Methoden werden in einem Task -Objekt gekapselt, wie im folgenden Codebeispiel gezeigt:

public async Task DeleteTodoItemAsync (string id)
{
  ...
  await Task.Factory.FromAsync (
    todoService.BeginDeleteTodoItem,
    todoService.EndDeleteTodoItem,
    id,
    TaskCreationOptions.None);
  ...
}

Die Task.Factory.FromAsync -Methode erstellt eine Task , die die TodoServiceClient.EndDeleteTodoItem -Methode nach Abschluss der TodoServiceClient.BeginDeleteTodoItem Methode ausführt, wobei der id Parameter die Daten sind, die an den BeginDeleteTodoItem Delegaten übergeben werden, um anzugeben, dass TodoItem vom Webdienst gelöscht werden soll. Schließlich gibt der Wert der TaskCreationOptions Enumeration an, dass das Standardverhalten für die Erstellung und Ausführung von Aufgaben verwendet werden soll.

Der Webdienst löst ein aus FaultException , wenn er nicht nach suchen oder löschen TodoItemkann, was von der Anwendung verarbeitet wird.

Konfigurieren des Remotezugriffs auf IIS Express

In Visual Studio 2017 oder Visual Studio 2019 sollten Sie die UWP-Anwendung auf einem PC ohne zusätzliche Konfiguration testen können. Das Testen von Android- und iOS-Clients erfordert möglicherweise die zusätzlichen Schritte in diesem Abschnitt. Weitere Informationen finden Sie unter Herstellen einer Verbindung mit lokalen Webdiensten über iOS-Simulatoren und Android-Emulatoren .

Standardmäßig reagieren IIS Express nur auf Anforderungen an localhost. Remotegeräte (z. B. ein Android-Gerät, ein iPhone oder sogar ein Simulator) haben keinen Zugriff auf Ihren lokalen WCF-Dienst. Sie müssen Ihre Windows 10 Arbeitsstations-IP-Adresse im lokalen Netzwerk kennen. Gehen Sie für dieses Beispiel davon aus, dass Ihre Arbeitsstation über die IP-Adresse verfügt 192.168.1.143. In den folgenden Schritten wird erläutert, wie Sie Windows 10 und IIS Express konfigurieren, um Remoteverbindungen zu akzeptieren und eine Verbindung mit dem Dienst von einem physischen oder virtuellen Gerät aus herzustellen:

  1. Fügen Sie eine Ausnahme zur Windows-Firewall hinzu. Sie müssen einen Port über die Windows-Firewall öffnen, über den Anwendungen in Ihrem Subnetz mit dem WCF-Dienst kommunizieren können. Erstellen Sie eine Eingangsregel, die Port 49393 in der Firewall öffnet. Führen Sie an einer Administratoreingabeaufforderung den folgenden Befehl aus:

    netsh advfirewall firewall add rule name="TodoWCFService" dir=in protocol=tcp localport=49393 profile=private remoteip=localsubnet action=allow
    
  2. Konfigurieren Sie IIS Express, um Remoteverbindungen zu akzeptieren. Sie können IIS Express konfigurieren, indem Sie die Konfigurationsdatei für IIS Express unter [Lösungsverzeichnis]vs\config\applicationhost.configbearbeiten. Suchen Sie das site Element mit dem Namen TodoWCFService. Es sollte ähnlich wie der folgende XML-Code aussehen:

    <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>
    

    Sie müssen zwei binding Elemente hinzufügen, um Port 49393 für externen Datenverkehr und den Android-Emulator zu öffnen. Die Bindung verwendet ein [IP address]:[port]:[hostname] Format, das angibt, wie IIS Express auf Anforderungen reagieren. Externe Anforderungen verfügen über Hostnamen, die als bindingangegeben werden müssen. Fügen Sie dem Element den bindings folgenden XML-Code hinzu, und ersetzen Sie die IP-Adresse durch Ihre eigene IP-Adresse:

    <binding protocol="http" bindingInformation="*:49393:192.168.1.143" />
    <binding protocol="http" bindingInformation="*:49393:127.0.0.1" />
    

    Nach den Änderungen sollte das bindings Element wie folgt aussehen:

    <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>
    

    Wichtig

    Standardmäßig akzeptieren IIS Express aus Sicherheitsgründen keine Verbindungen aus externen Quellen. Zum Aktivieren von Verbindungen von Remotegeräten müssen Sie IIS Express mit Administratorberechtigungen ausführen. Die einfachste Möglichkeit ist die Ausführung von Visual Studio 2017 mit Administratorberechtigungen. Dadurch wird beim Ausführen des TodoWCFService IIS Express mit Administratorberechtigungen gestartet.

    Nach Abschluss dieser Schritte sollten Sie in der Lage sein, den TodoWCFService auszuführen und eine Verbindung von anderen Geräten in Ihrem Subnetz herzustellen. Sie können dies testen, indem Sie Ihre Anwendung ausführen und besuchen http://localhost:49393/TodoService.svc. Wenn Sie beim Aufrufen dieser URL einen Fehler mit einer fehlerhaften Anforderung erhalten, ist ihre bindings in der IIS Express-Konfiguration möglicherweise falsch (die Anforderung erreicht IIS Express wird aber abgelehnt). Wenn Sie einen anderen Fehler erhalten, kann es sein, dass Ihre Anwendung nicht ausgeführt wird oder Ihre Firewall falsch konfiguriert ist.

    Damit IIS Express weiterhin den Dienst ausführen und bereitstellen können, deaktivieren Sie die Option Bearbeiten und Fortfahren unter Projekteigenschaften-Webdebugger >>.

  3. Passen Sie die Endpunktgeräte an, die für den Zugriff auf den Dienst verwendet werden. Dieser Schritt umfasst das Konfigurieren der Clientanwendung, die auf einem physischen oder emulierten Gerät ausgeführt wird, um auf den WCF-Dienst zuzugreifen.

    Der Android-Emulator verwendet einen internen Proxy, der verhindert, dass der Emulator direkt auf die Adresse des Hostcomputers localhost zugreift. Stattdessen wird die Adresse 10.0.2.2 im Emulator über einen internen Proxy an den Hostcomputer weitergeleitet localhost . Diese proxiierten Anforderungen haben 127.0.0.1 den Hostnamen im Anforderungsheader, weshalb Sie die IIS Express-Bindung für diesen Hostnamen in den obigen Schritten erstellt haben.

    Der iOS-Simulator wird auf einem Mac-Buildhost ausgeführt, auch wenn Sie den Remoted iOS Simulator für Windows verwenden. Bei Netzwerkanforderungen aus dem Simulator wird Ihre Arbeitsstations-IP im lokalen Netzwerk als Hostname verwendet (in diesem Beispiel ist dies 192.168.1.143der Fall, aber Ihre tatsächliche IP-Adresse ist wahrscheinlich anders). Aus diesem Grund haben Sie die IIS Express-Bindung für diesen Hostnamen in den obigen Schritten erstellt.

    Stellen Sie sicher, dass die SoapUrl Eigenschaft in der Datei Constants.cs im Projekt TodoWCF (Portable) über werte verfügt, die für Ihr Netzwerk korrekt sind:

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

    Nachdem Sie Constants.cs mit den entsprechenden Endpunkten konfiguriert haben, sollten Sie von physischen oder virtuellen Geräten aus eine Verbindung mit dem TodoWCFService herstellen können, der auf Ihrer Windows 10 Arbeitsstation ausgeführt wird.