Search code examples
c#wcfjson.netgrpcnetdatacontractserializer

Moving from WCF to gRPC, replacing NetDataContractSerializer


As part of moving from WCF to gRPC I am dealing with NetDataContractSerializer which is used for serializing objects on client side and de-serializing on server side. Both client and server are sharing same DLL with types used in communication.

As part of client app update process actual version of shared DLL with new/changed/deleted definitions of communication objects is downloaded from server. The basic communications objects used for update process are never changed. So serialization/deserialization during update works.

I would like to rewrite existing code as little as possible. I found out that I could replace NetDataContractSerializer by Newtonsoft's Json.NET serialization as described here: How to deserialize JSON to objects of the correct type, without having to define the type before hand? and here https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm.

But I wonder if:

  1. Is there better solution in general?
  2. Is there some solution based on what is part of .NET framework 4.8 and will be also working in .NET 5.0 without need to reference third-party DLL?
  3. Is there some binary-serialization alternative which would be more message-size friendly / faster? It is not mandatory for me to have sent messages in readable form.

Solution

  • On "3", gRPC is actually very open to you swapping out the serializer; you are not bound to protobuf, but gRPC is usually used with protobuf. In fact, you could actually use NetDataContractSerializer, although for reasons I'll come onto: I wouldn't recommend it.

    The "how" for this is hard to explain, because often with gRPC people use protoc to generate all the bindings, which hides all the details (and ties you to protobuf).

    You might be interested in protobuf-net.Grpc here, which is an alternative way of binding to gRPC (using the Google or Microsoft transports - it is just the bindings that are different), and which is much more comparable to WCF. In fact, it even allows you to borrow WCF's interface/attribute approach, although it doesn't give you like-for-like feature parity with WCF (it is still fundamentally gRPC!).

    For how, a getting started guide is here. The opening line sets the context:

    What is it?

    Simple gRPC access in .NET Core 3+ and .NET Framework 4.6.1+ - think WCF, but over gRPC

    It defaults to protobuf-net, which is an alternative protobuf serializer designed for code-first scenarios, but you can replace the serializer (globally, or for individual types). An example of implementing a custom serializer binding is provided here - note that most of that file is a large comment (the actual serializer code is 8-ish lines at the end). Please read those comments: they're notionally about BinaryFormatter, but every word of them applies equally to NetDataContractSerializer.

    I realise you said "without need to reference third-party DLL" - in which case, I mean sure: you could effectively spend a few weeks replicating the most immediately obvious things that protobuf-net.Grpc is doing for you, but ... that doesn't sound like a great use of your time if the NuGet package is simply sitting there ready to use. The relevant APIs are readily available to use with the Google/Microsoft packages, but there is quite a lot of plumbing involved in making everything work together.