zurück zum Artikel

Umstieg auf .NET Core, Teil 4: SOAP- und REST-Webservices umstellen

Dr. Holger Schwichtenberg
Umstieg auf .NET Core, Teil 4: SOAP- und REST-Webservices umstellen

(Bild: Piyawat Nandeenopparit/Shutterstock.com)

Während die Umstellung von ASP.NET WebAPI auf .NET Core noch überschaubar ist, macht die Umstellung WCF-basierter Webservices auf .NET Core viel Arbeit.

Das klassische .NET Framework bietet vier Arten von Verteilungstechniken an:

Umstieg auf .NET Core

In dieser fünfteiligen Artikelserie geht Holger Schwichtenberg der grundsätzlichen Frage nach, ob Organisationen, die zum Teil schon seit Anfang der 2000er Jahre mit dem klassischen .NET Framework entwickeln, ihren bestehenden Programmcode nun auf .NET Core umstellen sollten. Ist die Entscheidung für eine Migration gefallen, dann gilt es, eine Reihe von Herausforderungen zu meistern:

Heute stark verbreitet sind nur noch die beiden letztgenannten, wenngleich man immer noch einzelne Projekte mit .NET Remoting und ASMX findet. Das war auch insofern kein Problem als das klassisches .NET Framework von Version 1.0 (Jahr 2002) bis Version 4.8 (Jahr 2019) hinsichtlich der Funktionalität stabil blieb.

Mit dem Umstieg auf .NET Core beziehungsweise den für November 2020 angekündigten Nachfolger .NET 5.0 (ohne Core im Namen) kommt es zu – teils erheblichen – Brüchen für die Nutzer von Webservices.

In .NET Core gibt es mit ASP.NET Core WebAPI einen direkten Nachfolger des klassischen ASP.NET WebAPI. Wie bisher erfolgt die Serialisierung mit JSON oder XML – andere Serialisierer sind implementierbar. Für den Transport gibt es aber nur HTTP oder HTTPS. Für Metadaten in der OpenAPI-Spezifikation (ehemals "Swagger") stehen mit Swashbuckle [6] und NSwag [7] direkt zwei ergänzende Open-Source-Projekte zur Auswahl. Microsoft unterstützt die Integration von OpenAPI durch Hilfeseiten [8] und Werkzeuge wie die Proxy-Generierung mit "Add Connected Services" (s. Abb. 1). Alternativ lassen sich eigenständige Code-Generatoren wie NSwagStudio [9] nutzen.

Proxy-Generierung für Googles RPC-Dienste und WebAPIs mit OpenAPI-Metadaten in Visual Studio 2019 (Kontextmenüeintrag "Add Connected Services") (Abb. 1)

Proxy-Generierung für Googles RPC-Dienste und WebAPIs mit OpenAPI-Metadaten in Visual Studio 2019 (Kontextmenüeintrag "Add Connected Services") (Abb. 1)

Zwischen dem klassischen ASP.NET WebAPI (aktuelle Version 5.2.7 vom 29. November 2018) und ASP.NET Core WebAPI (aktuelle Version 3.1.1 vom 14. Januar 2020) sind einige Verhaltensunterschiede bei der Implementierung von Controller-Klassen und Aktionsmethoden sowie der Parameterbindung zu beachten:

Klassisches ASP.NET WebAPI 5.x ASP.NET Core 1.x und 2.0 ASP.NET Core seit 2.2
Entwicklung Eigenständiges Produkt Teil von ASP.NET Core MVC Teil von ASP.NET Core MVC
Basisklasse für die eigene Controller-Klasse ApiController Controller ControllerBase
Annotation Keine Keine [ApiController]
Komplexe Typen aus Query String [FromUri] Standard [FromQuery]
Komplexe Typen aus Form Data - [FromForm] [FromForm]
Komplexe Typen aus JSON-Body Standard [FromBody] Standard
Validierung Annotation + ModelState.IsValid() Annotation + ModelState.IsValid() Annotation + Automatische Fehlermeldung
Rückgabetypen HttpResponseMessage oder IHttpActionResult oder T ActionResult<T> oder IActionResult ActionResult<T> oder IActionResult oder T

Wie bei der Umstellung von WPF- und Windows Forms-Anwendungen [10] (Teil 2 der Serie) und ASP.NET-Websites [11] (Teil 3 der Serie), beginnt die Umstellung von ASP.NET WebAPI zu ASP.NET Core mit dem Anlegen eines neuen .NET Core-Projekts. Den Startcode und die Konfiguration der Anwendung muss man neu erstellen, die Controller und ergänzende Klassen kann man in das neue Projekt kopieren.

Zu den WebAPIs führen zwei unterschiedlich lange Wege: Der erste ist der kürzere, er vermeidet viele Code-Änderungen.

Microsoft bietet ein Kompatibilitätspaket Microsoft.AspNetCore.Mvc.WebApiCompatShim [12] an, mit dem die alte Basisklasse ApiController sowie in der klassischen WebAPI übliche Nachrichtenklassen wie HttpRequestMessage und HttpResponseMessage zur Verfügung stehen. Auch die Regel für Routing und Parameterbindung entsprechen mit diesem Paket der klassischen WebAPI.

Der zweite Weg, ohne das Kompatibilitätspaket, ist länger, weil mehr Programmcodeänderungen ) notwendig sind [13], führt aber zu WebAPIs, die dem neuen Standard in .NET Core entsprechen. Notwendige Änderungen betreffen die Basisklasse für Controller; sie ist nicht mehr ApiController, sondern Microsoft.AspNetCore.Mvc.ControllerBase. Ebenso ist der Rückgabetyp der Aktionsmethoden nicht mehr die Schnittstelle IHttpActionResult, sondern die Klasse ActionResult<T>. Verweise auf nicht mehr existierende Namensräume wie System.Web.Http sind zu löschen. Außerdem muss man das Routing (die zu einem Controller führende URL sowie das HTTP-Verb) mit den Annotationen, wie [Route], [HttpGet], [HttpPost], [HttpPut], [HttpDelete] usw. festlegen.

Eine weitere Herausforderung sind die Änderungen des JSON-Serializers. Microsoft verwendet seit ASP.NET Core 3.0 nicht mehr das in .NET Framework und .NET Core seit Jahren bevorzugte JSON.NET (alias Newtonsoft JSON), sondern hat mit System.Text.Json [14] eine neue eigene Bibliothek für JSON-Verarbeitung implementiert, die höhere Performance verspricht. Im Leistungstest ist System.Text.Json etwas performanter als JSON.NET, allerdings lassen sich die vom Entwicklungsteam verkündeten Geschwindigkeitszuwächse [15] von 1,5- bis zweifach für Serialisierung und Deserialisierung bisher nicht verifizieren (s. Abb. 2).

Leistungstest von System.Text.Json im Vergleich zu JSON.NET mit verschiedenen JSON-Dokumentgrößen (Abb. 2)

Leistungstest von System.Text.Json im Vergleich zu JSON.NET mit verschiedenen JSON-Dokumentgrößen (Abb. 2)

Allerdings ist System.Text.Json gegenüber JSON.NET funktional eingeschränkt. Microsoft bietet dazu eine längere Vergleichstabelle [16]. Der neue Serializer unterstützt zum Beispiel nicht die Datentypen BigInteger, TimeSpan, TimeZoneInfo, DBNull, ValueTuple, ExpandoObject, DataTable und DataRow.

Zahlreiche Verhaltensunterschiede im Detail finden sich insbesondere auch hinsichtlich der Strenge der Dateninterpretation. Dazu ein Beispiel: Während JSON.NET ein Datum auch in den Formen

2019-07-15T15:04:05.00+0100

und

2019-07-15T15:04:05.000+01:00

akzeptiert, gelingt eine Deserialisierung bei System.Text.Json allein mit dem Format

2019-07-15T15:04:05.000+01:00.

Diese Verhaltensunterschiede können dazu führen, dass WebAPIs beim Wechsel von der klassischen ASP.NET WebAPI zu ASP.NET Core WebAPI beziehungsweise ASP.NET Core WebAPI 1.x/2.x zu ASP.NET Core WebAPI 3.x nicht mehr wie gewohnt funktionieren.

Mögliche Inkompatibilitäten waren der Grund, warum James Newton-King, der Autor von JSON.NET, sich der vom .NET-Entwicklungsteam gewünschten inneren Umgestaltung von JSON.NET verweigert hat [17]. Zum Glück können Entwickler auch eine ASP.NET Core 3.x-basierte WebAPI wieder auf JSON.NET zurückschalten, in dem sie in der Startup-Klasse die Methode services.AddMvc().AddNewtonsoftJson() aus dem neuen NuGet-Paket Microsoft.AspNetCore.Mvc.NewtonsoftJson aufrufen.

Zu den genannten Aufwänden kommt bei der üblichen Nutzung von Webserver-APIs (bspw. Request- und Response-Header, Sessions, Caching, Authentifizierung) noch der Umstellungsaufwand hinzu, der schon in Teil 3 der Migrationsserie [18] beschrieben wurde und nicht nur Websites, sondern auch Web-APIs betrifft. Auch die allgemeinen Änderungen in den Basisklassen schlagen bei einer Migration von .NET Framework zu .NET Core bei den WebAPIs wieder durch (vgl. Teil 2 [19]).

Microsoft, einst ein Vorreiter bei der Spezifikation und Implementierung von SOAP (vier der acht Autoren der SOAP-1.1-Sepzifikation [20] waren bei Microsoft angestellt, ein fünfter wechselte kurz danach zu diesem Hersteller), hat sich von diesem Protokoll weitgehend verabschiedet.

Verwirrend ist für viele Benutzer die Situation um WCF in .NET Core. Seit WCF 2015 Open Source wurde [21], gibt es ein GitHub-Repository für WCF [22] auf .NET Core, das aber nur den Client-Teil von WCF enthält. Der erste Satz darin verdeutlicht es: "This repo contains the client-oriented WCF libraries that enable applications built on .NET Core to communicate with WCF services." Im weiteren Text stellt der Anbieter dann auch noch klar, dass es sich nur um eine Teilmenge der WCF-Funktionen handelt.

Die serverseitigen Bibliotheken von WCF, die auf einem Application Server benötigt würden, gibt es nicht in dem Repository. Auf GitHub wurde zwei Jahre lang hart über "Server Side WCF" diskutiert [23]. Auf der Build-Konferenz im Mai 2019 machte Microsoft dann deutlich: Die Übernahme von Klassen aus dem klassisches .NET Framework nach .NET Core ist nun abgeschlossen und WCF-Server gehören zu den Techniken, die Microsoft nicht mehr auf .NET Core portieren will [24].

Immerhin hat Microsoft den übrigen, bisher nicht portierten WCF-Quellcode freigegeben und fördert per Ankündigung vom 7. Juni 2019 die Portierung von WCF [25] durch die "Community" über die .NET Foundation [26].

Das Projekt heißt Core WCF [27] und ist laut Aussage auf der Website noch nicht einsatzreif: "Please note that right now, this port is not production ready.". Bis zur Veröffentlichung dieses Beitrags lag noch kein einziges Release in dem Projekt vor. Das definierte erste Ziel ist auch nicht die vollständige Kompatibilität zum klassischen WCF, sondern SOAP-Dienste via TCP und HTTP anbieten zu können. Die deutlich performantere binäre Serialisierung bleibt – zumindest vorerst – außen vor.

Die in .NET Core existierende WCF-Clientseite ist vielfältiger aufgestellt. Mit Ausnahme der nachrichtenbasierten Sicherheit mit WS-Security und einigen Windows-spezifischen Authentizierungsfeatures auf Linux und macOS sind alle Funktionen plattformneutral vorhanden [28].

Dennoch stellt sich die berechtigte Frage, ob man nicht nur darauf vertrauen darf, dass die Macher von Core WCF das Projekt jemals auf einen praxisreifen Stand bringen werden, sondern auch, ob sie gewillt sind, in Zukunft den Programmcode immer wieder an die Änderungen in den kommenden .NET-Versionen anzupassen. .NET 5.0 soll im November 2020 als Nachfolger von .NET Core 3.1 erscheinen. Danach gibt es jedes Jahr im November eine neue Hauptversion (.NET 6.0, .NET 7.0, .NET 8.0 usw.). Gemäß dem von Microsoft verfolgten Konzept des Semantic Versioning sind Breaking Changes in den Hauptversionen möglich und diese hat das Unternehmen beim Wechsel von .NET Core 1.x zu 2.0 und 2.x zu 3.0 auch zahlreich einfließen lassen. Sogar der Wechsel von .NET Core 3.0 zu 3.1 brachte Breaking Changes, die es eigentlich nicht hätte geben dürfen.

Für Core WCF bedeutet das jedoch, dass es auch in Zukunft immer wieder an die .NET-Hauptversionen angepasst werden muss. Das Problem lässt sich nur mildern, wenn man gewillt ist, bei Bedarf den Quellcode von Core WCF selbst anzupassen.

Angesichts dieser Herausforderungen stellt sich die Frage nach Alternativen zu Core WCF. Microsoft unterstützt neben den REST-basierten ASP.NET Core WebAPIs seit .NET Core 3.0 auch Google Remote Procedure Call (gRPC). Seitdem Microsoft sich der Open-Source-Welt geöffnet hat, gibt es auch keine Berührungsängste mit dem Suchmaschinenkonzern mehr.

gRPC verwendet als Transportprotokoll HTTP/2 (immer abgesichert mit SSL-/TLS-Transportsicherheit) und zur Serialisierung ein binäres Format mit Namen Protocol Buffers. Zu Protocol Buffers gehört auch ein textbasiertes Metadatenformat, das im Sinne des Contract-First-Designs der Ausgangspunkt der Entwicklung ist. Hieraus generiert der Protocol-Buffers-Compiler Quellcode in verschiedenen Programmiersprachen. Es existieren gRPC-Implementierungen für zahlreiche Programmierplattformen und -sprachen wie z.B. C++, C#, PHP, Java, Ruby, Python, Dart, Objective-C und JavaScript, nicht nur auf der Serverseite mit Node.js, sondern – in eingeschränkter Form – auch im Webbrowser (gRPC-Web [29]). Microsoft bietet seit 27. Januar 2020 eine .NET-basierte gRPC-Web-Implementierung [30], die ohne den bei gRPC üblichen Proxy auskommt. Somit können Blazor-WebAssembly-Anwendungen direkt mit gRPC-Diensten sprechen.

Microsoft und Google arbeiten zusammen an der C#-Implementierung von gRPC [31]. Hier taucht der bei Microsoft angestellte James Newton-King nun wieder als aktivster Entwickler auf. Microsoft liefert im .NET Core SDK (seit Version 3.0) und Visual Studio (seit Version 2019 16.3) Projektvorlagen für das Erstellen von gRPC-Servern. Ein gRPC-Server in .NET Core basiert auf ASP.NET Core. Ein Serverprozess kann sowohl WebAPI- als auch gRPC-Dienste hosten – unter verschiedenen URLs versteht sich. Allerdings können gRPC-Dienste derzeit nur im Kestrel-Webserver laufen. Weder die Internet Information Services (IIS) sowie die abgespeckte Version IIS Express noch ein Hosting in einem Azure App Service in der Cloud sind bislang möglich [32].

Aus der Sicht von Microsoft ist die Umstellung von WCF auf gRPC der favorisierte Weg, den der Softwarehersteller aus Redmond im Abschnitt Migrate a WCF solution to gRPC [33] in der Dokumentation zu gRPC auf .NET Core ausführlich beschreibt. Die Vorgehensweise erfordert jedoch umfassende Handarbeit.

Großen Aufwand verursacht zunächst das manuelle Erstellen der Protobuffers-Dienst- und Nachrichtenspezifikation im Textformat (.proto-Datei) auf Basis der WCF-Data- und Service-Vertragsklassen, die bei WCF in C#- oder Visual Basic-Syntax vorliegen. Mit dem Protobuffers-Compiler (NuGet-Paket Grpc.Tools) für C# generiert man in Visual Studio oder auf der Kommandozeile aus der .proto-Datei dann wieder C#-Programmcode. Es entstehen Klassen sowohl für die ein- und ausgehenden Nachrichten als auch abstrakte Basisklassen für die Dienste. Entwickler erstellen eine davon abgeleitete gRPC-Dienstklasse und überführen hier hinein dann die WCF-Service-Implementierung.

Eine Herausforderung ergibt sich dadurch, dass Protobuffers immer nachrichtenorientiert ist. Das heißt, es gibt bei Diensten keine primitiven Ein- und Ausgabeparameter, sondern immer jeweils eine ein- und ausgehende Nachrichtenklassen. Dies war auch bei WCF der empfohlene Weg in Hinblick auf Schnittstellenevolution, aber dennoch haben einige .NET-Entwickler mit primitiven Parametern gearbeitet. In diesem Fall ist der Weg zu gRPC etwas weiter.

Sofern man in der bisherigen Anwendung schon die von der Datenzugriffsschicht gelieferten Datenklassen auf eigene Nachrichtenklassen (alias Datentransferklassen) abgebildet hat, muss man nur das Mapping ändern. In WCF war es aber auch möglich, die Datenklassen der Datenzugriffsschicht direkt als Nachrichtenklassen zu verwenden. In dieser Architektur ist dann ein neues, zusätzliches Objekt-zu-Objekt-Mapping oder eine Änderung der Datenzugriffsschicht fällig.

Einen Client-Proxy für einen gRPC-Dienst können Entwickler in .NET Core- und .NET Standard-Projekten in Visual Studio komfortabel mit der integrierten Funktion "Add Connected Services" generieren lassen, wie in Abbildung 1 oben zu sehen.

Spannend ist die Frage, wie sehr man von der Umstellungsarbeit profitiert. Die Antwort liefert Abbildung 2. Die Leistung gRPC-basierter Dienste entspricht bei kleinen Nachrichten der Leistung von WCF mit TCP und Binärprotokoll – in der unverschlüsselten Form. Bei größeren Nachrichten bietet gRPC einen Vorteil.

Da gRPC aber stets Transport Layer Security (TLS) verwendet, ist der direkte Maßstab der dritte Block in der Grafik (WCF TCP + Verschlüsselung / binär). Da liegt gRPC schon deutlicher vorne. Klarer Sieger ist gRPC gegenüber WCF HTTP und HTTP-basierten WebAPIs. gRPC ist dabei verschlüsselt schneller als WCF und WebAPI unverschlüsselt. Der lange Balken in der Mitte ergibt sich daraus, dass bei der Messung bei WCF HTTP mit nachrichtenbasierter Sicherheit (WS-Security) statt Transportsicherheit (SSL/TLS) gearbeitet wurde. Bei gRPC gibt es weder WS-Security noch andere WS-+-Protokolle wie WS-Transaction, WS-Coordination, WS-ReliableMessaging, WS-Federation, WS-Policy und WS-Discovery.

Leistungsvergleich von WCF, WebAPI und gRPC mit einem direkten Datenbankzugriff (&quot;2-Tier&quot;) (Abb. 3)

Leistungsvergleich von WCF, WebAPI und gRPC mit einem direkten Datenbankzugriff ("2-Tier") (Abb. 3)

Alternativ zur Umstellung von WCF auf Google RPC könnte man auch von WCF auf ASP.NET Core WebAPI wechseln. Der Umstellungsaufwand ist grundsätzlich ähnlich. Es gibt aber Konverter für WSDL zu OAS (bspw. API Transformer [34] sowie weitere Open API Tools [35]) sowie Codegeneratoren, die aus einer OAS-Spezifikation WebAPI-Controller-Programmcode erzeugen. Swagger Hub [36] generiert aus OAS ein komplettes ASP.NET-Core-WebAPI-Projekt inklusive Startcode (s. Abb. 4). Mit diesen Werkzeugen kann man die Umstellung von WCF auf WebAPI vereinfachen.

Generierung eines ASP.NET-Core-WebAPI-Projekts aus einer OAS-Spezifikation mit Swagger Hub (Abb. 4)

Generierung eines ASP.NET-Core-WebAPI-Projekts aus einer OAS-Spezifikation mit Swagger Hub (Abb. 4)

Die Performance-Änderung bei der Umstellung von WCF auf WebAPI hängt dabei vom Ausgangspunkt ab: Wenn man vorher TCP als Transportprotokoll mit binärer Serialisierung eingesetzt hat, verliert man viel Leistung. Wenn man vorher HTTP mit SOAP ohne Sicherheit eingesetzt hat, ist die Leistung ohne Sicherheit nun ähnlich. WebAPI mit SSL/TLS ist aber performanter als WCF HTTP mit WS-Security (s. Abb. 3).

WebAPI empfiehlt sich gegenüber gRPC, wenn man Webbrowser als Clients hat. Die gRPC-Implementierung für Webbrowser ist noch nicht ebenbürtig zum sonst üblichen gRPC-Funktionsumfang [37] ("Nicht alle Funktionen von gRPC werden von gRPC-Web unterstützt. Client und bidirektionales Streaming werden nicht unterstützt, und es gibt nur eingeschränkte Unterstützung für Server Streaming.") wie die nachfolgende Abbildung 5 zeigt.

Wenn bei WCF Duplex-Kommunikation eingesetzt wurde, muss man dies in der Welt von WebAPIs mit ASP.NET Core SignalR [38] nachbilden, denn die Grundausstattung der WebAPIs kann nur uni- und bidirektional kommunizieren.

Microsoft

Vergleich gRPC mit ASP.NET Core WebAPI (Abb. 5)

(Bild: Microsoft [39])

Außerhalb von Microsoft gibt es noch andere Kommunikationsalternativen in der .NET Core-Welt:

Wer im klassischen .NET Framework REST-basierte WebAPIs genutzt hat, für den liegt der Umstieg auf ASP.NET Core WebAPIs nahe. Bei größeren Projekten ist tendenziell – zumindest zunächst – das Kompabilitätspaket Microsoft.AspNetCore.Mvc.WebApiCompatShim zu bevorzugen, außer man ist in der glücklichen Lage, entgegen dem Markttrend genug Entwicklerressourcen für die kompletten Umstellungsarbeiten zu haben. Vorhandene automatische Tests der WebAPI-Schicht helfen hier natürlich, die Korrektheit der Routen, Parameterbindung und Rückgabestrukturen zu prüfen.

Nutzer von WCF-Servern können abwarten und auf Core WCF hoffen oder die Umstellung auf Google RPC auf sich nehmen. Die erwähnten Alternativen sind als Nischenprodukte Geschmackssache. Der Autor dieses Beitrags plädiert dafür, für fundamentale Funktionen wie die Webservice-Kommunikation ein Framework zu wählen, das Microsoft oder ein anderer großer Hersteller selbst pflegen, also ASP.NET Core WebAPI oder Google RPC.

Dr. Holger Schwichtenberg (@DOTNETDOKTOR [43])

ist einer der bekanntesten Experten für .NET und Webtechniken in Deutschland. Zusammen mit 35 weiteren Experten unterstützt er im Rahmen der Firma www.IT-Visions.de [44] mittlere und große Unternehmen durch Beratung und Schulungen beim Erstellen von Windows- und Webanwendungen. Zudem hat er einige Fachbücher zu .NET, PowerShell und JavaScript/TypeScript veröffentlicht.. (map [45])


URL dieses Artikels:
https://www.heise.de/-4705706

Links in diesem Artikel:
[1] https://www.heise.de/hintergrund/Umstieg-auf-NET-Core-Migrieren-oder-nicht-migrieren-4628946.html
[2] https://www.heise.de/hintergrund/Umstieg-auf-NET-Core-Desktop-Anwendungen-mit-WPF-und-Windows-Forms-umstellen-4640058.html
[3] https://www.heise.de/hintergrund/Umstieg-auf-NET-Core-ASP-NET-Webserveranwendungen-umstellen-4687175.html
[4] https://www.heise.de/hintergrund/Umstieg-auf-NET-Core-Teil-4-SOAP-und-REST-Webservices-umstellen-4705706.html
[5] Datenzugriff auf .NET Core umstellen
[6] https://github.com/domaindrivendev/Swashbuckle.AspNetCore
[7] https://github.com/RicoSuter/NSwag
[8] https://docs.microsoft.com/de-de/aspnet/core/tutorials/web-api-help-pages-using-swagger?view=aspnetcore-3.1
[9] https://github.com/RicoSuter/NSwag/wiki/NSwagStudio
[10] https://www.heise.de/hintergrund/Umstieg-auf-NET-Core-Desktop-Anwendungen-mit-WPF-und-Windows-Forms-umstellen-4640058.html
[11] https://www.heise.de/hintergrund/Umstieg-auf-NET-Core-ASP-NET-Webserveranwendungen-umstellen-4687175.html
[12] https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.WebApiCompatShim
[13] https://docs.microsoft.com/en-us/aspnet/core/migration/webapi?view=aspnetcore-3.1
[14] https://www.nuget.org/packages/System.Text.Json
[15] https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis
[16] https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to
[17] https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis
[18] https://www.heise.de/hintergrund/Umstieg-auf-NET-Core-ASP-NET-Webserveranwendungen-umstellen-4687175.html
[19] https://www.heise.de/hintergrund/Umstieg-auf-NET-Core-Desktop-Anwendungen-mit-WPF-und-Windows-Forms-umstellen-4640058.html
[20] https://www.w3.org/TR/2000/NOTE-SOAP-20000508/
[21] https://www.heise.de/news/NET-Kommunikationsplattform-WCF-ist-Open-Source-2660553.html
[22] https://github.com/dotnet/wcf
[23] https://github.com/dotnet/wcf/issues/1200#issuecomment-356422289
[24] https://www.heise.de/developer/meldung/Build-2019-Microsoft-konkretisiert-die-Plaene-fuer-NET-5-0-4416914.html
[25] https://devblogs.microsoft.com/dotnet/supporting-the-community-with-wf-and-wcf-oss-projects
[26] https://dotnetfoundation.org/blog/2019/06/07/welcoming-core-wcf-to-the-net-foundation
[27] https://github.com/CoreWCF/CoreWCF
[28] https://github.com/dotnet/wcf/blob/master/release-notes/SupportedFeatures-v2.1.0.md
[29] https://github.com/grpc/grpc-web
[30] https://devblogs.microsoft.com/aspnet/grpc-web-experiment
[31] https://github.com/grpc/grpc-dotnet
[32] https://github.com/dotnet/AspNetCore/issues/9020
[33] https://docs.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/migrate-wcf-to-grpc
[34] https://www.apimatic.io/transformer/
[35] https://openapi.tools/
[36] https://app.swaggerhub.com/
[37] https://docs.microsoft.com/de-de/aspnet/core/grpc/comparison?view=aspnetcore-3.1
[38] https://docs.microsoft.com/de-de/aspnet/core/signalr/introduction?view=aspnetcore-3.1
[39] https://docs.microsoft.com/de-de/aspnet/core/grpc/comparison?view=aspnetcore-3.1
[40] https://github.com/DigDes/SoapCore
[41] https://github.com/jacqueskang/IpcServiceFramework
[42] https://servicestack.net/
[43] http://twitter.com/dotnetdoktor
[44] https://www.it-visions.de/
[45] mailto:map@ix.de