.Net Core上的WsHttpBinding

问题描述

我正在将一个.Net 4.x项目迁移到.Net Core 3.1。该项目在很大程度上取决于SOAP Web服务。由于.Net Core不支持基于配置的WCF服务使用,因此我通过代码调用该服务。当前项目使用ws2007HttpBinding绑定。

我的问题是ws2007HttpBinding中不存在.Net Core。除了HttpBindingHttpsBindingCustomBinding外,我别无选择。我用不同的配置尝试了所有这些,但是每次遇到错误。有时它抱怨https方案(我正在使用的服务是https),有时它说它期望text/xml但没有看到它,这可能是由于不同的SOAP协议导致的双方都在使用,有时我会收到超时错误

在上一次尝试中,我安装了Microsoft.NETCore.Platforms 3.1.2System.ServiceModel.Http 4.7.0以及更高的4.8.0-preview3.20412.3。后者具有WsHttpBindingWs2007HttpBinding的实现。但是,两者都不起作用。这次我出现错误

System.NotSupportedException:不支持指定的方法

任何解决方案或建议都将受到高度赞赏。

这是堆栈跟踪和部分代码

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

代码

        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;

解决方法

核心不支持Wshttpbinding,wcf仅支持BasicHttpBinding,CustomBinding,NetHttpBinding,NetTcpBinding:

enter image description here

因此,目前有两种解决方案:

修改服务器的绑定,请勿使用Wshttpbinding。

客户端继续使用.net框架。

有关核心中的WCF功能的更多信息,您可以参考以下链接:

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