{"id":1250,"date":"2021-01-26T12:47:58","date_gmt":"2021-01-26T12:47:58","guid":{"rendered":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?p=1250"},"modified":"2021-01-27T13:52:46","modified_gmt":"2021-01-27T13:52:46","slug":"wcf-alternatives-part-2","status":"publish","type":"post","link":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/","title":{"rendered":"WCF Alternatives (Part 2) \u2013 Instructions for the Migration from WCF to Web API"},"content":{"rendered":"\n<p>This blog post in the <a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/topic\/wcf-alternatives\/\">series on alternatives for the Windows Communication Foundation (WCF)<\/a> describes the particularities and challenges regarding a WCF migration in preparation of the subsequent porting of the application to .NET Core.<\/p>\n\n\n\n<p>This post will first address ASP.NET Core Web API as a possible alternative, and describe, step by step, how a migration from WCF to ASP.NET Core Web API can be done. The procedure for the migration to gRPC, on the other hand, is described in the next blog post.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"vorgehen-bei-der-migration-9a6a2230-2400-477d-89b7-3e1549ef6210\"><strong>Migration<\/strong> procedure<\/h2>\n\n\n\n<p>Usually, there is a separate WCF project in the solution. As a direct conversion is not possible, this project can remain unchanged in the solution for the time being.<\/p>\n\n\n\n<p>You should first create a new class library project for shared objects between the server and the client. Then copy the ServiceContract interfaces and the DataContract classes from the WCF project to this project, and remove the WCF-specific attributes such as \u201cServiceContract\u201d, \u201cOperationContract\u201d, \u201cDataContract\u201d, \u201cDataMember\u201d, etc.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"client-projekt-236d5945-79de-4574-8abe-4b93f45af705\"><strong>Client project<\/strong><\/h3>\n\n\n\n<p>First of all, remove the WCF Service reference in the project that consumes the WCF Service. The WCF-specific attributes such as \u201cCallbackBehavior\u201d and the like can be removed as well.<\/p>\n\n\n\n<p>Add a new reference to the previously created class library project for the shared objects.<\/p>\n\n\n\n<p>Next, you can create an empty implementation of the ServiceContract interface, which is now located in the class library project, in the client project.<\/p>\n\n\n\n<p>Now change the \u201cold\u201d initialization of the WCF Service to the, as-yet empty, implementation of the ServiceContract.<\/p>\n\n\n\n<p>Lastly, you have to change the usings for the previously used DataContract classes from the WCF Service to the new class library project. It should now be possible to compile the client project again. In order to be able to start the project again, you have to remove the &lt;system.serviceModel&gt; from the *.config.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"webapiprojekt-a90411bd-81db-422c-84cc-2536c56aac91\"><strong>Web API project<\/strong><\/h3>\n\n\n\n<p>Create a \u201cstandard\u201d ASP.NET Core Web API project for the new server, and add a reference to the new class library project. This is necessary to enable the server to use the same replacement classes (previously DataContract) as the client.<\/p>\n\n\n\n<p>Now create a controller for each previous WCF ServiceContract in the Web API. For starters, the implementation can be adopted from the \u201cold\u201d WCF Service. Subsequently, the return values have to be changed to ActionResult and ActionResult&lt;T&gt;, respectively. The [Http..] verb attributes and a route for each method have to be specified. Furthermore, the [ProducesResponseType] attribute should be specified for each method; it describes the expected return value and will later be used for the generation of the client.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[ServiceContract(CallbackContract = typeof(IDataCallback))]\npublic interface IDataInputService\n{\n    [OperationContract]\n    int CreateUser(User user);\n\n    [OperationContract]\n    int Login(User user);\n\n    [OperationContract]\n    List&lt;Time> GetTimes(int userId);\n\n    [OperationContract]\n    void AddTime(Time time, int userId);\n\n    [OperationContract]\n    List&lt;string> Projects();\n}<\/pre>\n\n\n\n<p><em>Example of a WCF Service Contract to be migrated<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[Route(\"api\/TimeService\")]\n[ApiController]\npublic class TimeServiceController : ControllerBase\n{    \n    [HttpPost(\"CreateUser\")]\n    [ProducesResponseType(typeof(int), 200)]\n    public ActionResult&lt;int> CreateUser(User user)\n    {\n \n    }\n\n    [HttpPost(\"Login\")]\n    [ProducesResponseType(typeof(int), 200)]\n    public ActionResult&lt;int> Login(User user)\n    {\n\t\t\n    }\n\n    [HttpGet(\"Times\")]\n    [ProducesResponseType(typeof(List&lt;Time>), 200)]\n    public ActionResult&lt;List&lt;Time>> GetTimes(int userId)\n    {\n        \n    }\n\n    [HttpPost(\"AddTime\")]\n    [ProducesResponseType(200)]\n    public ActionResult AddTime(Time time, int userId)\n    {\n        \n    }\n\n    [HttpGet(\"Projects\")]\n    [ProducesResponseType(typeof(List&lt;string>), 200)]\n    public ActionResult&lt;List&lt;string>> Projects()\n    {\n        \n    }\n}<\/pre>\n\n\n\n<p><em>Example of the created Web API controller<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Note: <\/strong>The Web API controller created this way will probably not correspond to a resource-oriented REST API. The API is more action-based and reflects the \u201cold\u201d Service\u2014which is no problem for the transition for now.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Client gener<\/strong>ation<\/h3>\n\n\n\n<p>To avoid writing a lot of code for calling and using the Web API, you can generate it. The OpenAPI specification (formerly Swagger) can be used for this purpose.<\/p>\n\n\n\n<p>There are several ways to generate the OpenAPI specification and, based thereon, the client code. One of these options is described below as an example.<\/p>\n\n\n\n<p>In order for the OpenAPI specification to be generated automatically, you must first integrate the \u201cNSwag.AspNetCor\u201d NuGet package and configure it in the Web API project according to the instructions given in <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.microsoft.com\/de-de\/aspnet\/core\/tutorials\/getting-started-with-nswag\" target=\"_blank\">Getting started with NSwag<\/a>. After that, you can already test the API interface in the browser by calling up the \/swagger\/ URL once the Web API project has been started.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"518\" height=\"600\" src=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_Swagger_Overview_en-518x600.jpg\" alt=\"Swagger overview\" class=\"wp-image-1279\" srcset=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_Swagger_Overview_en-518x600.jpg 518w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_Swagger_Overview_en-640x741.jpg 640w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_Swagger_Overview_en.jpg 699w\" sizes=\"auto, (max-width: 639px) 98vw, (max-width: 1199px) 64vw, 518px\" \/><figcaption><em>Figure 1: Swagger<\/em> <em>overview<\/em><\/figcaption><\/figure>\n\n\n\n<div style=\"height:29px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"571\" height=\"600\" src=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_Swagger_Detail_en-571x600.jpg\" alt=\"Swagger detail\" class=\"wp-image-1280\" srcset=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_Swagger_Detail_en-571x600.jpg 571w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_Swagger_Detail_en-640x672.jpg 640w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_Swagger_Detail_en.jpg 676w\" sizes=\"auto, (max-width: 639px) 98vw, (max-width: 1199px) 64vw, 571px\" \/><figcaption><em>Figure 2: Swagger detail<\/em><\/figcaption><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The client code for access to the new Web API can be generated with <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/RicoSuter\/NSwag\/wiki\/NSwagStudio\" target=\"_blank\">NSwagStudio<\/a>. In the settings of the generator, make sure that the namespace for the generation of the client is correct. Additional settings may be required for specific projects until the desired result is generated. The client created by the generator and the settings made in the generator (*.nswag file) should be saved in the project.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"419\" src=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_NSwag_Studio_en-600x419.jpg\" alt=\"NSwag Studio generator\" class=\"wp-image-1281\" srcset=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_NSwag_Studio_en-600x419.jpg 600w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_NSwag_Studio_en-1024x714.jpg 1024w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_NSwag_Studio_en-768x536.jpg 768w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_NSwag_Studio_en-640x446.jpg 640w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_NSwag_Studio_en-1200x837.jpg 1200w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2021\/01\/202012_NSwag_Studio_en.jpg 1250w\" sizes=\"auto, (max-width: 639px) 98vw, (max-width: 1199px) 64vw, 600px\" \/><figcaption><em>Figure 3: NSwag Studio generator<\/em><\/figcaption><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Use of the c<strong>lient<\/strong><\/h3>\n\n\n\n<p>When the generator generates the desired result, you only need to make one more change to integrate the new client. The previously created, as-yet empty dummy implementation of the ServiceContract only has to inherit from the newly generated client, and the empty implementation has to be removed. It is important to ensure that the newly created client fulfills the ServiceContract interface.<\/p>\n\n\n\n<p>The migration from WCF to Web API is now complete and should be tested.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Bidirectional communication<\/strong><\/h3>\n\n\n\n<p>If bidirectional communication was used in the WCF Service, it must now be realized by means of SignalR.<\/p>\n\n\n\n<p>For this purpose, create a hub class that inherits from Microsoft.AspNetCore.SignalR.Hub for each WCF CallbackContract in the Web API project. In the Startup.cs of the Web API project, add the line \u201cservices.AddSignalR();\u201d in the ConfigureServices method. In the Configure method, a mapping is provided in the definition of UseEndpoints for each hub &#8220;endpoints.MapHub&lt;EarningsHub&gt;(&#8220;\/Earnings&#8221;);&#8221;.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class Startup\n{    \n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddSignalR();\n    }\n\n    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n    {       \n        app.UseEndpoints(endpoints =>\n        {            \n            endpoints.MapHub&lt;EarningsHub>(\"\/Earnings\");\n        });\n    }\n}\n\npublic class EarningsHub : Microsoft.AspNetCore.SignalR.Hub\n{\n\t\n}<\/pre>\n\n\n\n<p><em>Changes to the Web API startup class and definition of the SignalR Hub<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>By injecting IHubContext&lt;EarningsHub&gt;, you can trigger the transmission of data to all or specific clients with just one line.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[Route(\"api\/TimeService\")]\n[ApiController]\npublic class TimeServiceController : ControllerBase\n{\n    private readonly IHubContext&lt;EarningsHub> earningsHubContext;\n    public TimeServiceController(IHubContext&lt;EarningsHub> earningsHubContext)\n    {\n        this.earningsHubContext = earningsHubContext;\n    }\n\n    [HttpPost(\"AddTime\")]\n    [ProducesResponseType(200)]\n    public ActionResult AddTime(Time time, int userId)\n    {\n        Task.Run(async () => await earningsHubContext.Clients.All.SendAsync(\"EarningsCalculated\", result)).GetAwaiter().GetResult();\n    }\n}<\/pre>\n\n\n\n<p><em>Use of the SignalR hub in the API controller<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Subsequently, add the \u201cMicrosoft.AspNetCore.SignalR.CIient\u201d NuGet package to the consuming project. As you can see in the example below, the method previously called by the server does not have to be changed at all. In WCF, the method was triggered by means of the callback interface and its allocation upon initialization of the client with \u201cnew InstanceContext(this)\u201d. With the SignalR implementation, a connection to the hub is established, and the triggering server event is bound to the existing method.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext = false)]\npublic partial class TimeTracking : Page, IDataInputServiceCallback\n{\n    private DataInputServiceClient client;\n    \n    public TimeTracking()\n    { \n        client = new DataInputServiceClient(new InstanceContext(this));\n    }\n\n    public void EarningsCalculated(Dictionary&lt;int, decimal> earnings)\n    {\n        \/\/ Client Methode welche vom Server aufgerufen wird\n    }\n}\n\n[ServiceContract(CallbackContract = typeof(IDataCallback))]\npublic interface IDataInputService\n{\n    \n}\n\npublic interface IDataCallback\n{\n    [OperationContract(IsOneWay = true)]\n    void EarningsCalculated(IDictionary&lt;int, decimal> earnings);\n}<\/pre>\n\n\n\n<p><em>Client example using the WCF CallbackContract<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public partial class TimeTracking : Page\n{\n    private HubConnection connection;\n    \n    public TimeTracking()\n    {    \n        connection = new HubConnectionBuilder().WithUrl(\"http:\/\/localhost:52841\/Earnings\").Build();\n        connection.On&lt;Dictionary&lt;int, decimal>>(\"EarningsCalculated\", EarningsCalculated);\n        connection.StartAsync();\n    }\n\t\n    public void EarningsCalculated(Dictionary&lt;int, decimal> earnings)\n    {\n        \/\/ Client Methode welche vom Server aufgerufen wird\n    }\n}<\/pre>\n\n\n\n<p><em>Client example after conversion to SignalR<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The use of SignalR described here as an example is very simple. For a productive deployment, you should ensure a robust implementation with automatic reconnect etc., see also: <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.microsoft.com\/de-de\/aspnet\/core\/signalr\/dotnet-client?view=aspnetcore-3.1&amp;tabs=visual-studio\" target=\"_blank\">https:\/\/docs.microsoft.com\/de-de\/aspnet\/core\/signalr\/dotnet-client?view=aspnetcore-3.1&amp;tabs=visual-studio<\/a><\/p>\n\n\n\n<p><strong>Cross-cutting concerns<\/strong> such as authentication, authorization, logging and error handling of the Web API calls have not been considered in the migration. These issues should be checked and adjusted as well in each individual case.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>The conversion from WCF to ASP.NET Core Web API is possible and relatively easily manageable. The implementation of the WCF Services can be directly adopted for the new Web API controllers with minor adjustments to the return values and attributes. Using the OpenAPI specification allows you to generate a client for access to the Web API that supports the previous WCF ServiceContract interface. This way, only a few usings and the initialization of the client have to be adjusted in the consuming application.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post will first address ASP.NET Core Web API as a possible alternative, and describe, step by step, how a migration from WCF to ASP.NET Core Web API can be done.<\/p>\n","protected":false},"author":105,"featured_media":1223,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","footnotes":""},"categories":[8,13],"tags":[27,360,629,630,640,641],"topics":[642],"class_list":["post-1250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web","category-dot-net","tag-asp-net-core","tag-web-api","tag-wcf","tag-windows-communication-foundation","tag-migration","tag-grpc","topics-wcf-alternatives"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog<\/title>\n<meta name=\"description\" content=\"This post will address ASP.NET Core Web API as a possible alternative for WCF, and describe how a migration can be done.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog\" \/>\n<meta property=\"og:description\" content=\"This post will address ASP.NET Core Web API as a possible alternative for WCF, and describe how a migration can be done.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Digital Innovation Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-26T12:47:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-01-27T13:52:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1404\" \/>\n\t<meta property=\"og:image:height\" content=\"791\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"David Siebert\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"David Siebert\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/\",\"name\":\"WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies.png\",\"datePublished\":\"2021-01-26T12:47:58+00:00\",\"dateModified\":\"2021-01-27T13:52:46+00:00\",\"author\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/6b51a72db3cce2762c3e7ba935cf25bf\"},\"description\":\"This post will address ASP.NET Core Web API as a possible alternative for WCF, and describe how a migration can be done.\",\"breadcrumb\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#primaryimage\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies.png\",\"contentUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies.png\",\"width\":1404,\"height\":791},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"WCF Alternatives (Part 2) \u2013 Instructions for the Migration from WCF to Web API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/\",\"name\":\"Digital Innovation Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/6b51a72db3cce2762c3e7ba935cf25bf\",\"name\":\"David Siebert\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/siebert_david-e1607418544482-150x150.jpg\",\"contentUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/siebert_david-e1607418544482-150x150.jpg\",\"caption\":\"David Siebert\"},\"description\":\"David Siebert is Senior Consultant Software Development at ZEISS Digital Innovation. His focus is primarily on .NET development. In addition, he is particularly involved with web technologies and clean code.\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/endavidsiebert\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog","description":"This post will address ASP.NET Core Web API as a possible alternative for WCF, and describe how a migration can be done.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/","og_locale":"en_US","og_type":"article","og_title":"WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog","og_description":"This post will address ASP.NET Core Web API as a possible alternative for WCF, and describe how a migration can be done.","og_url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/","og_site_name":"Digital Innovation Blog","article_published_time":"2021-01-26T12:47:58+00:00","article_modified_time":"2021-01-27T13:52:46+00:00","og_image":[{"width":1404,"height":791,"url":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies.png","type":"image\/png"}],"author":"David Siebert","twitter_card":"summary_large_image","twitter_misc":{"Written by":"David Siebert","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/","name":"WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog","isPartOf":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#primaryimage"},"image":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies.png","datePublished":"2021-01-26T12:47:58+00:00","dateModified":"2021-01-27T13:52:46+00:00","author":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/6b51a72db3cce2762c3e7ba935cf25bf"},"description":"This post will address ASP.NET Core Web API as a possible alternative for WCF, and describe how a migration can be done.","breadcrumb":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#primaryimage","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies.png","contentUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies.png","width":1404,"height":791},{"@type":"BreadcrumbList","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wcf-alternatives-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/"},{"@type":"ListItem","position":2,"name":"WCF Alternatives (Part 2) \u2013 Instructions for the Migration from WCF to Web API"}]},{"@type":"WebSite","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/","name":"Digital Innovation Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/6b51a72db3cce2762c3e7ba935cf25bf","name":"David Siebert","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/image\/","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/siebert_david-e1607418544482-150x150.jpg","contentUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/siebert_david-e1607418544482-150x150.jpg","caption":"David Siebert"},"description":"David Siebert is Senior Consultant Software Development at ZEISS Digital Innovation. His focus is primarily on .NET development. In addition, he is particularly involved with web technologies and clean code.","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/endavidsiebert\/"}]}},"author_meta":{"display_name":"David Siebert","author_link":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/endavidsiebert\/"},"featured_img":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2021\/01\/202101_WCF_communication_technologies-600x338.png","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Web<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/dot-net\/\" class=\"advgb-post-tax-term\">.NET<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">Web<\/span>","<span class=\"advgb-post-tax-term\">.NET<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/dot-net\/\" class=\"advgb-post-tax-term\">ASP.NET Core<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/dot-net\/\" class=\"advgb-post-tax-term\">Web API<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/dot-net\/\" class=\"advgb-post-tax-term\">WCF<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/dot-net\/\" class=\"advgb-post-tax-term\">Windows Communication Foundation<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/dot-net\/\" class=\"advgb-post-tax-term\">Migration<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/dot-net\/\" class=\"advgb-post-tax-term\">gRPC<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">ASP.NET Core<\/span>","<span class=\"advgb-post-tax-term\">Web API<\/span>","<span class=\"advgb-post-tax-term\">WCF<\/span>","<span class=\"advgb-post-tax-term\">Windows Communication Foundation<\/span>","<span class=\"advgb-post-tax-term\">Migration<\/span>","<span class=\"advgb-post-tax-term\">gRPC<\/span>"]}},"comment_count":"0","relative_dates":{"created":"Posted 5 years ago","modified":"Updated 5 years ago"},"absolute_dates":{"created":"Posted on January 26, 2021","modified":"Updated on January 27, 2021"},"absolute_dates_time":{"created":"Posted on January 26, 2021 12:47 pm","modified":"Updated on January 27, 2021 1:52 pm"},"featured_img_caption":"","series_order":"","_links":{"self":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/1250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/users\/105"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/comments?post=1250"}],"version-history":[{"count":6,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/1250\/revisions"}],"predecessor-version":[{"id":1283,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/1250\/revisions\/1283"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/media\/1223"}],"wp:attachment":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/media?parent=1250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/categories?post=1250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/tags?post=1250"},{"taxonomy":"topics","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/topics?post=1250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}