wcf icon indicating copy to clipboard operation
wcf copied to clipboard

Please provide comprehensible information about WCF in .NET Core

Open arphox opened this issue 4 years ago • 10 comments

Hi!

I am writing this issue to recommend You to provide comprehensible information about WCF in .NET Core. Please let me justify why I recommend it with some facts:

Intro

  • Searching for "wcf in .net core" on google shows the "What replaces WCF in .Net Core?" question as first result which has an accepted answer starting with "WCF is not supported in .NET Core". Based on this, a developer could suppose that there is no WCF in .NET Core. Fortunately, this is not entirely true.
  • Link to this repository (dotnet/wcf) is rather easy to find and the description says that here are "client-oriented WCF libraries" (which I did not understand first; "what is client-oriented?"). Alright, so it seems that I can consume WCF services in .NET Core. Let us find out how.
  • I could not find any developer guide for .NET Core in WCF. For the .NET framework version, there are a lot of material (though they do not really clearly state that applies only for .NET Framework), but for .NET Core, none on docs.microsoft.com as I saw.

Configuration opportunities

.NET Framework: you add a service reference to the project, and XML-based configuration will be generated to your app.config file, inside the <system.serviceModel> tag. This is fine and required (if you remove this configuration, your code won't work). For different enviroments (test, prod) you only have to change the XML configuration (e.g. ASP.NET web.config files as transforms).

.NET Core: XML-based configuration does not really exist since in .NET Core, the place for settings (as far as I know) is the appsettings.json file, and had no idea how to configure it in configuration files.

  • I have found the generated ConnectedService.json which turned out is only used for the client generation tool. (Turned out from a github issue, not a documentation or guide or so which is sad for me).
  • With lack of official documentation about this area, I had to google and I have found the article "Using WCF With .NET Core" by Jon Seeley; and there he states there is no built-in file configuration opportunities for WCF in .NET Core and he constructed a solution for it. But he abandoned it when he saw that the .NET Core version is a lot worse in terms of performance (1/3 as fast). So now, two questions arises in my head:
  • How to configure WCF in .NET Core with files? -> sure, for hello world applications, your library works out of the box, but if it is not configurable outside of code, it is not really usable for applications in production or for anything serious in general.
  • Is the performance really that bad? And why? -> I was planning to migrate our WCF client code to .NET Core until I found out that this can be a lot slower than in .NET Framework. Now I am stuck; will we need to migrate it to gRPC when we want to switch to .NET Core? Is a gRPC client even compatible with a WCF service? Or does it need a "gRPC service"?

Of course I found code in the generated Reference.cs file for client classes which have several constructors those allow to inject various EndpointConfiguration, endpoint addresses and so on; but is this the only way to configure it (again, I repeat, I miss documentation so much)? If yes, that means we will have to build our own file config management system (sections, elements, etc) and create clients with those settings, but all these require a lot of extra code.

Closing words

In my opinion, the best place for such documentation and knowledge base would be here, in this repository; I say that it should be at the beginning of the README, because developers are simply lost without information like these. And under documentation I do not only mean the answers for my questions, but a complete guide to what a WCF has been and what it will be in the future, from the client side.

Looking for advice

I also would like to ask advice about our production application: currently, we have a .NET Framework application which has like ~12 WCF service reference along with generated client code those are tens of thousands line of code. We only use WCF for consuming. We have a NuGet package which encapsulates and simplify all these communication and our main business applications use this NuGet package to communicate with the service. The services are third party for us, so we cannot change their side.
We configure this NuGet in our ASP.NET applications' Web.config file (and tests' app.config file); all these in .NET Framework. We want to update our NuGet to .NET Standard so our new .NET Core-based "ASP.NET Core" services will also be able to use this NuGet. So both our legacy and new systems will be able to work on the same NuGet.
I think this is (or will be) a relatively common scenario in the future and it would be great if you could give some advice related this question.

Thank you very much in advance!

arphox avatar Jan 16 '20 07:01 arphox

I forgot to mention it but there is one more general question.
I have found the CoreWCF/CoreWCF repository which also seems to be a .NET Core WCF implementation, and even the .NET foundation wrote an article about this repository.
This (dotnet/wcf) repository seems a lot more authentic for me than the CoreWCF repository, but still the question arises? Who are They, who are You, why do we need two different .NET Core WCF implementation, and why the .NET foundation funds two different projects for this?

arphox avatar Jan 16 '20 07:01 arphox

@arphox Thanks for taking the time to provide this feedback. I agree our documentation is less than ideal. I do have a task to do some work related to this topic. I'll keep this issue assigned to me so we can incorporate youor feedback into the planned work. Thanks.

StephenBonikowsky avatar Jan 23 '20 22:01 StephenBonikowsky

@arphox I did test CoreWCF/CoreWCF with ours open source project 'Crema'. CoreWCF is not good choice.

  1. Performance is so bad!
  2. Implementation is not good. examples, PerSession scenarios, not good WCF Behavior.
  3. Many not supports.

powerumc avatar Feb 03 '20 23:02 powerumc

@mconnew @arphox Regarding the CoreWCF repository.

I recently responded on another issue with information that is relevant to your question about what is the dotnet/wcf repository. https://github.com/dotnet/wcf/issues/4079#issuecomment-580551893

The short version is that Microsoft with this repo is supporting WCF Client side functionality only.

The WCF Server side functionality is going into the CoreWCF repo and while all the initial work to get it to a workable state is being done by a Microsoft employee, it is a "community owned" open source project. It is not yet in a 'production ready' state but work is continuing to get it there.

@powerumc CoreWCF is not yet production ready and is under active development.

StephenBonikowsky avatar Feb 03 '20 23:02 StephenBonikowsky

arphox described my exact experience over the last day. I'm very thankful this project exists and is even integrated into Visual Studio now, but am missing the configuration. I'm taking a stab at recreating it using the Option pattern (and just noticed the HttpBinding does not have the HostNameComparisonMode property it had in .NET Framework, which led me here.)

xr280xr avatar Jul 07 '20 20:07 xr280xr

Hello @StephenBonikowsky any news on How to configure WCF in .NET Core with files?

We need to set ClientCredentialType to Certificate but can't find how to set it with a config file.

At https://docs.microsoft.com/en-us/dotnet/framework/wcf/how-to-set-the-security-mode they show how to do in .Net Framework:

<wsHttpBinding>
<binding name="TransportSecurity">
    <security mode="Transport" >
       <transport clientCredentialType = "Certificate" />
    </security>
</binding>
</wsHttpBinding >

For now, I'm setting it in GetBinding For Endpoint, but it get override when I update the service image

eduardogoncalves avatar Jan 25 '21 21:01 eduardogoncalves

@HongGit and @mconnew can you help with this question?

StephenBonikowsky avatar Jan 25 '21 22:01 StephenBonikowsky

Hello @StephenBonikowsky any news on How to configure WCF in .NET Core with files?

We need to set ClientCredentialType to Certificate but can't find how to set it with a config file.

At https://docs.microsoft.com/en-us/dotnet/framework/wcf/how-to-set-the-security-mode they show how to do in .Net Framework:

<wsHttpBinding>
<binding name="TransportSecurity">
    <security mode="Transport" >
       <transport clientCredentialType = "Certificate" />
    </security>
</binding>
</wsHttpBinding >

For now, I'm setting it in GetBinding For Endpoint, but it get override when I update the service image

I found out you can pass the binding as a parameter when you create a new client.

Example:

System.ServiceModel.BasicHttpBinding customBinding = new System.ServiceModel.BasicHttpBinding();
customBinding.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
customBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

ServiceReference.ServiceClient myServiceClient = new ServiceReference.ServiceClient (customBinding ,new EndpointAddress("YourEndPointURLHere"));

Hope this helps.

telsonalva avatar Mar 23 '21 11:03 telsonalva

just noticed the HttpBinding does not have the HostNameComparisonMode property it had in .NET Framework, which led me here

It would be good to have a list of changed or removed settings. I figured out Realm was unnecessary now, but if the properties have name or values changed there's no information

ellenhutchings avatar Dec 08 '21 01:12 ellenhutchings

The .NET Portability Analyzer tool will analyze your code and tell you which api's you are using which aren't available. Some things are just unnecessary, for example HostNameComparisonMode is a service side only property. It's used to control whether WCF cares if the endpoint hostname matches the hostname in the request, which is obviously only applicable to a service.

There are some gray areas to this which are unfortunately unavoidable. We have some api's which we can't support, but are there as a holdover from Windows 8 Store App days. We inherited our api surface from there. One example is passing a configuration name to a ChannelFactory constructor. We try to fail fast whenever this is the case and throw an exception straight away. Other possible areas are when we accept an enum for a property. One example of this is passing SecurityMode.Message to a binding. The api analyzer won't be able to tell you there's a problem there but we'll throw at runtime when you create the binding. Basically, if the analyzer sees everything is good, it's probably okay, but there's a few areas where it won't catch it.

We haven't changed names of properties anywhere that I am aware of. We've kept as much compatibility as we can and try to throw an explicit PlatformNotSupportedException if we know it's not supported. The only area which has changed is things which are WSTrust/WSFederation related. In that area, we've kept things familiar so it should be relatively simple to convert across.

If there's an api that's missing, many of them we can easily add. Often the implementation is there, it just hasn't been exposed because it wasn't in the initial API surface area we inherited and nobody has asked for it yet. Also sometimes there were multiple ways to do things, so we've only brought over the single mechanism. For example, you used to be able to call the static method EndpointIdentity.CreateDnsIdentity as well as directly instantiate DnsEndpointIdentity. We don't have the static factory method any more so if you are using it, you have to directly instantiate the type. There's only a few places like that though.

mconnew avatar Dec 08 '21 21:12 mconnew