Migrating From WCF to gRPC
And communicate cross-platform between a Node.js client and a C# Windows Service

Microsoft Windows Communication Foundation (WCF) has always been my go-to communication framework on Windows.
I love to be able to change protocol and format through configuration.
- Do you need the broadest interoperability with other systems and languages? You use WsHttpBinding.
- Do you need the highest speed between two processes on the same machine? You use NetNamedPipeBinding.
But, to my regret, Microsoft did not migrate WCF to the .Net Core platform. The .Net Core platform is cross-platform, and Microsoft tightly coupled WCF to the Windows operating system. The tight coupling makes it difficult for them to migrate WCF.
In this article, I will describe how and why I migrated from WCF to gRPC. As gRPC is cross-platform, I will show an example that communicates between a .Net Core service and a Node.js client.
I use Visual Studio 2019 for creating the ASP.Net Core gRPC service and Visual Studio Code for the Node.js client.
At the end of the article, I will list alternatives to gRPC.
Why would you Migrate?
The reason to migrate away from WCF is simple. Microsoft recommends using .Net Core for all new application development. As Microsoft .Net Core does not support WCF, you have to migrate.
You could decide not to migrate at all and stay with the Microsoft .Net framework. A valid option, but you won’t be doing yourself a favor. Microsoft’s future investment in .NET will be in .NET Core.
Microsoft recommends gRPC as the WCF alternative on .Net Core.
Are there alternatives? Yes, you could use HTTP APIs or Websockets. But be aware that HTTP APIs are less performant, and Websockets need manual work for message serialization.
What is the difference between WCF and gRPC?
The most significant difference between WCF and gRPC are in the following areas:
- Interface definition
- Protocol and format
- Error handling
- Security
Interface definition
With WCF, you describe the interface of your service through a C# interface. The WCF server generates WSDL through reflection at runtime. Client generators use the WSDL to create clients for the service.
gRPC uses Protocol Buffers to describe the interface. So, you have to define your communication interface using this Protocol Buffer definition language. You have to store this in a .proto
file. Various generators are available that use the .proto
file to generate client and server stubs.
Protocol Buffers is a custom language. This makes gRPC independent of a platform and language. Each platform and language can develop generators to generate clients and service stubs.
Protocol and Format
With WCF, you can use configuration to choose different communication protocols and formats. For example, HTTP, TCP, MSMQ, or named pipes. The protocol and format are specified using bindings — for instance, NetTcp binding.
gRPC uses HTTP/2 for the networking protocol and a binary message format. gRPC offers the same speed and efficiency as WCF NetTcp binding. In some cases, even higher speed.
Error handling
With WCF, you can use FaultException<TDetail>
to provide error information that conforms to the SOAP Fault standard.
gRPC does not have this extended error handling. gRPC uses status codes and metadata. The following table shows the most used status codes.
GRPC_STATUS_UNIMPLEMENTED
The method has not been implementedGRPC_STATUS_UNAVAILABLE
The service has a general problem and is not available.GRPC_STATUS_INTERNAL
The service has a problem with encoding/decoding messages.GRPC_STATUS_UNAUTHENTICATED
The authentication on the server failedGRPC_STATUS_PERMISSION_DENIED
The client has no authorization to perform the requested actionGRPC_STATUS_CANCELLED
The client canceled the call
Security
With WCF, you have a lot of security options. Do you want yo use Message Level encryption or Value encryption? What kind of authentication do you want? Active Directory Integration, Kerberos, LDAP, etc.
gRPC uses HTTP/2. Although it is possible to use unencrypted data over HTTP/2, all major browsers only support HTTP/2 over TLS. So HTTP/2 will always use encrypting using TLS. So will gRPC.
You can use Client and Server certificates for authentication. If you want to use call level authorization, you can use tokens, for instance, JSON Web Tokens (JWT).
Now let's examine what is gRPC.
What is gRPC?
General-purpose Remote Procedure Calls (gRPC) is an open-source communication framework initially developed by Google. No, the g does not stand for Google. It uses Google’s Protocol Buffers to describe the communication interface.
Protocol buffers are a cross-platform mechanism for serializing data.
You have to describe the communication interface in a .proto file. The .proto file contains definitions of all message types. gRPC includes generators for many different languages, such as:
- Java
- Python
- Objective-C
- C++
- Dart
- Go
- Ruby
- C#
A gRPC example

Let's look at an example. The .proto file below defines a service called Graph DefinitionService. This service contains two methods. One for retrieving a single Graph Definition and another for reading all Graph Definitions.
The first line defines the syntax
of the proto that you want to use. There are two versions available, “proto2” and “proto3”. I recommend using version 3 because it supports more languages.
Row three contains an option
statement. These statements are specific to a language. In this case for C#, so when using a java generator the charp_
options are ignored.
The package
definition in line five is essential. It defines the name of the service.
Service methods
The service
statement on line seven starts the methods that will be available on your service. Each method begins with rpc
. You can compare this with the OperationContract on a WCF service.
Each method on the gRPC service accepts a message and returns a message. It is not possible to have a single integer argument or return a void.
Message definition
A message definition starts with the keyword message. For instance, in row 12, the message GetRequest is defined. This message contains a single field called graphDefinitionId of type int32.
Protocol Buffer supports several native data types such as int32, double, and string. There is no native GUID of UUID data type available, which I frequently use as an Id field. The best way to resolve this is to use a string instead.
After each field in a message definition, there is a unique number. This number identifies the field in the binary message. Therefore, you should assign a number and never change it if your message type is in use.
Even if you don’t need a field anymore, you can remove the field, but you shouldn’t reuse the field number. Just leave gaps.
Creating the gRPC service
Although it is possible to create a gRPC service using Visual Studio Code, I will be using Visual Studio 2019. Visual Studio 2019 makes the process much easier.
Visual Studio contains a project template for creating a gRPC service. This template generates an ASP.NET Core 3.1 project. It contains a service and an example .proto
file.

Visual Studio translates the .proto
file into C#partial classes with virtual methods during the build. You can derive from these partial classes and implement the service methods by overriding. See below for an example implementation of the GraphDefinitionService.
The complete solution is available on GitHub.
Creating a .Net Core gRPC client
I will first create a gRPC client using Visual Studio 2019. I use a .Net Core console project.
Then install the following Nuget packages using the Package Manager Console in Visual Studio.
- Install-Package Grpc.Net.Client
- Install-Package Google.Protobuf
- Install-Package Grpc.Tools
Copy or link the GraphDefinitionService.proto to the Client program. Select the proto file and set the correct compilation properties. Make sure that the property gRPC Sub Classes is Client only.

The following program connects to the GraphDefinitionService gRPC service and calls the GetAsync
method.
Creating a Node.js gRPC client
To demonstrate the cross-platform abilities, I also implemented a Node.js gRPC client.
The Node.js client needs the following two NPM packages.
npm install grpc @grpc/proto-loader
It also needs access to the graphdefinitionservice.proto
file to be able to generate the stub classes.
In contrast to C#, the Node.js gRPC libraries generate the communication stub during runtime. On line 16, the proto file is loaded, and Node.js generates a stub. The client creates the actual connection to the service on line 18.
On line 23, the client makes the actual call to the service. The full source is available on Github.
Migrating from WCF to gRPC
gRPC can be an excellent alternative to WCF. But as you probably have a lot of time and energy invested in your WCF services. You might be interested in the possibility to automatically migrate your WCF services.
Visual ReCode is a commercial Visual Studio plugin that helps to migrate your WCF services to gRPC. Visual ReCode scans the projects in your solution and searches all WCF interfaces by scanning for the [OperationContract]
attribute.
It then lets you select the WCF interface that you want to migrate. After selection it creates for each interface:
- A proto file based on the original WCF interface
- A gRPC service that implements the proto file and calls the original code
- A gRPC client that is able to call all the methods of the gRPC service.
Still, you will need to do some manual work. But if you need to migrate a lot of WCF services I would recommend checking out Visual ReCode. A trial version is available.
Conclusion and alternatives
In this article, we saw that Microsoft does not support WCF on .Net Core. You can use gRPC, which is a valid alternative for creating high-speed services. Other options are Basic HTTP APIs and Websockets.
We implemented a gRPC ASP .NET Core service and Node.js client. The source is available on Github.
If you want to migrate your WCF services to gRPC, you can do it manually or use a tool. Especially if you have a lot of WCF services, a tool like Visual ReCore can help.
An alternative for WCF that I did not mention before is Core WCF. Core WCF is an open-source port of Windows Communication Framework (WCF) to .NET Core. Currently, it is not production-ready. But in the future, it may be an alternative that can run WCF services on .Net Core.
Before you start converting your WCF services to gRPC, there are two things I want to share. At the time of writing this article, it is not possible to run gRPC in IIS. IIS does not support HTTP/2.
The same is true for Azure App Services. They use IIS, and so don’t yet support gRPC. I suspect that Microsoft will add support later this year.
Thank you for reading and stay safe.