WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog (2024)

This blog post in the series on alternatives for the Windows Communication Foundation (WCF) describes the particularities and challenges regarding a WCF migration in preparation of the subsequent porting of the application to .NET Core.

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.

Migration procedure

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.

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 “ServiceContract”, “OperationContract”, “DataContract”, “DataMember”, etc.

Client project

First of all, remove the WCF Service reference in the project that consumes the WCF Service. The WCF-specific attributes such as “CallbackBehavior” and the like can be removed as well.

Add a new reference to the previously created class library project for the shared objects.

Next, you can create an empty implementation of the ServiceContract interface, which is now located in the class library project, in the client project.

Now change the “old” initialization of the WCF Service to the, as-yet empty, implementation of the ServiceContract.

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 <system.serviceModel> from the *.config.

Web API project

Create a “standard” 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.

Now create a controller for each previous WCF ServiceContract in the Web API. For starters, the implementation can be adopted from the “old” WCF Service. Subsequently, the return values have to be changed to ActionResult and ActionResult<T>, 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.

[ServiceContract(CallbackContract = typeof(IDataCallback))]public interface IDataInputService{ [OperationContract] int CreateUser(User user); [OperationContract] int Login(User user); [OperationContract] List<Time> GetTimes(int userId); [OperationContract] void AddTime(Time time, int userId); [OperationContract] List<string> Projects();}

Example of a WCF Service Contract to be migrated

[Route("api/TimeService")][ApiController]public class TimeServiceController : ControllerBase{ [HttpPost("CreateUser")] [ProducesResponseType(typeof(int), 200)] public ActionResult<int> CreateUser(User user) { } [HttpPost("Login")] [ProducesResponseType(typeof(int), 200)] public ActionResult<int> Login(User user) { } [HttpGet("Times")] [ProducesResponseType(typeof(List<Time>), 200)] public ActionResult<List<Time>> GetTimes(int userId) { } [HttpPost("AddTime")] [ProducesResponseType(200)] public ActionResult AddTime(Time time, int userId) { } [HttpGet("Projects")] [ProducesResponseType(typeof(List<string>), 200)] public ActionResult<List<string>> Projects() { }}

Example of the created Web API controller

Note: 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 “old” Service—which is no problem for the transition for now.

Client generation

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.

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.

In order for the OpenAPI specification to be generated automatically, you must first integrate the “NSwag.AspNetCor” NuGet package and configure it in the Web API project according to the instructions given in Getting started with NSwag. 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.

WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog (1)
WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog (2)

The client code for access to the new Web API can be generated with NSwagStudio. 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.

WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog (3)

Use of the client

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.

The migration from WCF to Web API is now complete and should be tested.

Bidirectional communication

If bidirectional communication was used in the WCF Service, it must now be realized by means of SignalR.

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 “services.AddSignalR();” in the ConfigureServices method. In the Configure method, a mapping is provided in the definition of UseEndpoints for each hub “endpoints.MapHub<EarningsHub>(“/Earnings”);”.

public class Startup{ public void ConfigureServices(IServiceCollection services) { services.AddSignalR(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseEndpoints(endpoints => { endpoints.MapHub<EarningsHub>("/Earnings"); }); }}public class EarningsHub : Microsoft.AspNetCore.SignalR.Hub{}

Changes to the Web API startup class and definition of the SignalR Hub

By injecting IHubContext<EarningsHub>, you can trigger the transmission of data to all or specific clients with just one line.

[Route("api/TimeService")][ApiController]public class TimeServiceController : ControllerBase{ private readonly IHubContext<EarningsHub> earningsHubContext; public TimeServiceController(IHubContext<EarningsHub> earningsHubContext) { this.earningsHubContext = earningsHubContext; } [HttpPost("AddTime")] [ProducesResponseType(200)] public ActionResult AddTime(Time time, int userId) { Task.Run(async () => await earningsHubContext.Clients.All.SendAsync("EarningsCalculated", result)).GetAwaiter().GetResult(); }}

Use of the SignalR hub in the API controller

Subsequently, add the “Microsoft.AspNetCore.SignalR.CIient” 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 “new InstanceContext(this)”. With the SignalR implementation, a connection to the hub is established, and the triggering server event is bound to the existing method.

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext = false)]public partial class TimeTracking : Page, IDataInputServiceCallback{ private DataInputServiceClient client; public TimeTracking() { client = new DataInputServiceClient(new InstanceContext(this)); } public void EarningsCalculated(Dictionary<int, decimal> earnings) { // Client Methode welche vom Server aufgerufen wird }}[ServiceContract(CallbackContract = typeof(IDataCallback))]public interface IDataInputService{ }public interface IDataCallback{ [OperationContract(IsOneWay = true)] void EarningsCalculated(IDictionary<int, decimal> earnings);}

Client example using the WCF CallbackContract

public partial class TimeTracking : Page{ private HubConnection connection; public TimeTracking() { connection = new HubConnectionBuilder().WithUrl("http://localhost:52841/Earnings").Build(); connection.On<Dictionary<int, decimal>>("EarningsCalculated", EarningsCalculated); connection.StartAsync(); } public void EarningsCalculated(Dictionary<int, decimal> earnings) { // Client Methode welche vom Server aufgerufen wird }}

Client example after conversion to SignalR

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: https://docs.microsoft.com/de-de/aspnet/core/signalr/dotnet-client?view=aspnetcore-3.1&tabs=visual-studio

Cross-cutting concerns 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.

Conclusion

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.

This post was written by:

David Siebert

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.

See author's posts

WCF Alternatives (Part 2) - Instructions ... - ZEISS Digital Innovation Blog (2024)
Top Articles
Offshore Decommissioning Market Trends: In-Depth Analysis and Key Player Insights for 2032
Learn how to make money on Snapchat
Scheelzien, volwassenen - Alrijne Ziekenhuis
Craigslist Livingston Montana
NYT Mini Crossword today: puzzle answers for Tuesday, September 17 | Digital Trends
Access-A-Ride – ACCESS NYC
The Idol - watch tv show streaming online
Gameplay Clarkston
Apply A Mudpack Crossword
What is the surrender charge on life insurance?
Ap Chem Unit 8 Progress Check Mcq
Oxford House Peoria Il
Hope Swinimer Net Worth
Hair Love Salon Bradley Beach
Sand Castle Parents Guide
Nutrislice Menus
ARK: Survival Evolved Valguero Map Guide: Resource Locations, Bosses, & Dinos
Missed Connections Dayton Ohio
Geometry Review Quiz 5 Answer Key
Walmart Car Department Phone Number
Lola Bunny R34 Gif
Is A Daytona Faster Than A Scat Pack
All Obituaries | Gateway-Forest Lawn Funeral Home | Lake City FL funeral home and cremation Lake City FL funeral home and cremation
Wkow Weather Radar
No Limit Telegram Channel
Nearest Ups Ground Drop Off
Stockton (California) – Travel guide at Wikivoyage
Annapolis Md Craigslist
Himekishi Ga Classmate Raw
1964 Impala For Sale Craigslist
How To Make Infinity On Calculator
NIST Special Publication (SP) 800-37 Rev. 2 (Withdrawn), Risk Management Framework for Information Systems and Organizations: A System Life Cycle Approach for Security and Privacy
#scandalous stars | astrognossienne
Moxfield Deck Builder
Chris Provost Daughter Addie
Wildfangs Springfield
Skill Boss Guru
Merkantilismus – Staatslexikon
2 Pm Cdt
Lovely Nails Prices (2024) – Salon Rates
Tripadvisor Vancouver Restaurants
Foxxequeen
Deepwoken: How To Unlock All Fighting Styles Guide - Item Level Gaming
N33.Ultipro
Dragon Ball Super Card Game Announces Next Set: Realm Of The Gods
Windy Bee Favor
Mejores páginas para ver deportes gratis y online - VidaBytes
Erespassrider Ual
Assignation en paiement ou injonction de payer ?
Nfhs Network On Direct Tv
Kobe Express Bayside Lakes Photos
Latest Posts
Article information

Author: Errol Quitzon

Last Updated:

Views: 6061

Rating: 4.9 / 5 (79 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Errol Quitzon

Birthday: 1993-04-02

Address: 70604 Haley Lane, Port Weldonside, TN 99233-0942

Phone: +9665282866296

Job: Product Retail Agent

Hobby: Computer programming, Horseback riding, Hooping, Dance, Ice skating, Backpacking, Rafting

Introduction: My name is Errol Quitzon, I am a fair, cute, fancy, clean, attractive, sparkling, kind person who loves writing and wants to share my knowledge and understanding with you.