Issues integrating .Net Core and WCF

Stephen Richardson 41 Reputation points
2022-03-23T13:30:23.237+00:00

I've found a couple of problems integrating .Net Core and WCF. These are:

1) If I write a service that exposes a custom class and then try to return this from a WCF service it will throw an exception if any property of the class doesn't have a public setter.

2) I have a net.tcp connection to a WCF service. If I don't use any authentication on the connection everything works OK but if I add it and set the ClientCredentialType then the authentication fails. It works fine with a .Net Framework 4.x application. (If I remove the ClientCredentialType line everything works but only if the service and app are on the same box).

    NetTcpBinding binding1 = new NetTcpBinding();
    binding1.Security.Mode = SecurityMode.Transport;
    binding1.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
    binding1.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
    binding1.ReceiveTimeout = TimeSpan.MaxValue;
    binding1.ReliableSession.InactivityTimeout = TimeSpan.MaxValue;
    binding1.MaxReceivedMessageSize = 2147483647;
    binding1.MaxBufferSize = 2147483647;
    binding1.TransferMode = TransferMode.Streamed;
    ServiceHost.AddServiceEndpoint(typeof(IService1), binding1, baseAddress);
    ServiceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByIssuerName, "acme.com");

3) It's not possible to update a WCF service reference within VS2022, I have to keep deleting it and adding it again.

Does anyone know how to solve these problems?

Developer technologies .NET Other
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Michael Taylor 60,161 Reputation points
    2022-03-23T16:03:04.423+00:00

    .NET Core only supports WCF as a client so I'm assuming you're writing your WCF service in .NET Framework.

    1) This isn't surprising but ultimately would depend on the serializer being used. Without a setter the value cannot be set which means it would be a calculated value. On the client side that wouldn't matter though. Therefore I would just make the client model allow setting. This would be especially important because serialization in .NET Core isn't the same as .NET Framework. But showing the definition and error(s) would help clarify.
    2) Just a guess there is an issue with the TLS protocol and/or cert on the client machine. Ensure the server and client are using the same TLS protocols and that the cert is available on both machines.
    3) In the Connected Services UI next to the Add button should be a refresh button. If you press that what happens?

    0 comments No comments

  2. Stephen Richardson 41 Reputation points
    2022-03-23T16:52:29.403+00:00

    1) Yes my WCF service is running in a .Net Framework 4 app and the problem only occurs if I mark the operations with [XmlSerializerFormat] to prevent the property names being changed when I create the WCF service reference in my .Net 6 app.

    2) The certificate is installed on the client - I will check the TLS versions.

    3) When I click refresh nothing seems to happen - the service creation dialog doesn't open up again and the code behind doesn't update to reflect any changes made on the server side.


  3. Stephen Richardson 41 Reputation points
    2022-03-23T17:39:58.82+00:00

    For completeness here is the WCF service code (running on .Net 4.x)

    ServiceHost = new ServiceHost(typeof(Service1));
    string baseAddress = "net.tcp://localhost:8733/Design_Time_Addresses/WpfServiceHost/Service1";
    NetTcpBinding binding1 = new NetTcpBinding();
    binding1.Security.Mode = SecurityMode.Transport;
    binding1.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
    binding1.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
    binding1.Security.Transport.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
    binding1.ReceiveTimeout = TimeSpan.MaxValue;
    binding1.ReliableSession.InactivityTimeout = TimeSpan.MaxValue;
    binding1.MaxReceivedMessageSize = 2147483647;
    binding1.MaxBufferSize = 2147483647;
    binding1.TransferMode = TransferMode.Streamed;
    ServiceHost.AddServiceEndpoint(typeof(IService1), binding1, baseAddress);
    ServiceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByIssuerName, "acme.com");
    
    ServiceHost.Open();
    

    I've now set the TLS protocol versions on the server and client sides but the connection still fails if I include the line where binding1.Security.Transport.ClientCredentialType is set or if I run the server and client on different boxes.

    Updated client code:

    NetTcpBinding tcpBinding = new NetTcpBinding();
    tcpBinding.ReceiveTimeout = TimeSpan.MaxValue;
    tcpBinding.MaxReceivedMessageSize = 2147483647;
    tcpBinding.MaxBufferSize = 2147483647;
    tcpBinding.Security.Mode = SecurityMode.Transport;
    tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
    tcpBinding.Security.Transport.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
    tcpBinding.TransferMode = TransferMode.Streamed;
    testService = new TestServiceRef1.Service1Client(tcpBinding, new EndpointAddress(new Uri("net.tcp://myserver:8733/Design_Time_Addresses/WpfServiceHost/Service1")));
    testService.ChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
    
    testService.Open();
    

  4. Stephen Richardson 41 Reputation points
    2022-03-24T13:52:57.957+00:00

    If found the problem. My original WCF service was hosted in a Windows Service running under the system account but for this test I hosted the service in a WPF app which ran under my Windows user account. When I recreated the Windows Service setup for this test service I was able to call it from .Net 6 successfully with the code above - no need to use TcpClientCredentialType.Certificate

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.