2

I'm migrating a .Net 4.x project to .Net Core 3.1. This project is heavily dependent on SOAP web services. As .Net Core does not support configuration based WCF service consumption, I call the service by code. Current project uses ws2007HttpBinding binding.

My problem is that ws2007HttpBinding does not exists officially in .Net Core. I have no option other than HttpBinding, HttpsBinding and CustomBinding. I have tried all of them with different configurations, but each time encounter an error. Sometime it complaint about https scheme (service which I am using is https), sometimes it says it has expected text/xml but has not seen it, and it maybe a result of different SOAP protocls each side is using, and sometimes I just get timeout error.

In my last try, I installed Microsoft.NETCore.Platforms 3.1.2 and System.ServiceModel.Http 4.7.0 and later 4.8.0-preview3.20412.3. The latter has implenetations of both WsHttpBinding and Ws2007HttpBinding. But, neither worked. This time I got error:

System.NotSupportedException: Specified method is not supported.

Any solution or suggestion is highly appreciated.

Here it is the stack trace and parts of the code:

System.AggregateException: One or more errors occurred. (Specified method is not supported.)
 ---> System.NotSupportedException: Specified method is not supported.
   at System.ServiceModel.MessageSecurityOverHttp.CreateSecurityBindingElement(Boolean isSecureTransportMode, Boolean isReliableSession, MessageSecurityVersion version)
   at System.ServiceModel.WSHttpSecurity.CreateMessageSecurity(Boolean isReliableSessionEnabled, MessageSecurityVersion version)
   at System.ServiceModel.WSHttpBinding.CreateMessageSecurity()
   at System.ServiceModel.WSHttpBindingBase.CreateBindingElements()
   at System.ServiceModel.WSHttpBinding.CreateBindingElements()
   at System.ServiceModel.Channels.Binding.EnsureInvariants(String contractName)
   at System.ServiceModel.Description.ServiceEndpoint.EnsureInvariants()
   at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint, Boolean useActiveAutoClose)
   at System.ServiceModel.ChannelFactory.CreateFactory()
   at System.ServiceModel.ChannelFactory.OnOpening()
   at System.ServiceModel.Channels.CommunicationObject.System.ServiceModel.IAsyncCommunicationObject.OpenAsync(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.OpenAsyncInternal(TimeSpan timeout)
   at System.Runtime.TaskHelpers.WaitForCompletion(Task task)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open()
   at System.ServiceModel.ChannelFactory.EnsureOpened()
   at System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address, Uri via)
   at System.ServiceModel.ChannelFactory`1.CreateChannel()
   at System.ServiceModel.ClientBase`1.CreateChannel()
   at System.ServiceModel.ClientBase`1.CreateChannelInternal()
   at System.ServiceModel.ClientBase`1.get_Channel()
   at client.Inquiry_DataAsync(String NationalCode) in C:\Users\Reference.cs:line 5577
   at class1.<>c__DisplayClass13_0.<Inquiry_Data>b__0() in C:\Users\Code.cs:line 349
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification

code:

        PermissiveCertificatePolicy.Enact("*");

        var binding = new WSHttpBinding();

        binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

        ServiceClient client = new ServiceClient(
            binding, new EndpointAddress("https://example.com/service.svc"));
        client.ClientCredentials.UserName.UserName = username;
        client.ClientCredentials.UserName.Password = password;
        client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = X509RevocationMode.NoCheck
        };

        _result = Task.Run(() => client.InquiryDataAsync("ABC")).Result;
Afshar Mohebi
  • 10,479
  • 17
  • 82
  • 126

1 Answers1

1

Core does not support Wshttpbinding, wcf only supports BasicHttpBinding, CustomBinding, NetHttpBinding, NetTcpBinding:

enter image description here

So there are two current solutions:

Modify the binding of the server, do not use Wshttpbinding.

The client continues to use the .net framework.

For more information about WCF Features in core, you can refer to this link:

https://github.com/dotnet/wcf/blob/master/release-notes/SupportedFeatures-v2.1.0.md

Ding Peng
  • 3,702
  • 1
  • 5
  • 8
  • I can't modify server binding, we have not control on it. Moreever, `System.ServiceModel.Http` has a limited support of `WsHttpBinding`. Unfortunately, this support is not enough in my case. – Afshar Mohebi Sep 07 '20 at 06:02
  • In this case, the client can only use the .net framework. – Ding Peng Sep 07 '20 at 06:06