After some struggles, I managed to create a WCF service that could be consumed by the class library. But it only supports the Custombinding. Please refer to the below example.
Server-side (a console application based on Dotnet Framework 4.7.2)
class Program { static void Main(string[] args) { Uri uri = new Uri("http://localhost:21011"); MtomMessageEncodingBindingElement encoding = new MtomMessageEncodingBindingElement(); var transport = new HttpTransportBindingElement(); transport.TransferMode = TransferMode.Streamed; var binding = new CustomBinding(encoding, transport); using (ServiceHost sh = new ServiceHost(typeof(MyService), uri)) { sh.AddServiceEndpoint(typeof(IService), binding, ""); ServiceMetadataBehavior smb; smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>(); if (smb == null) { smb = new ServiceMetadataBehavior() { HttpGetEnabled = true }; sh.Description.Behaviors.Add(smb); } Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding(); sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex"); sh.Opened += delegate { Console.WriteLine("Service is ready"); }; sh.Closed += delegate { Console.WriteLine("Service is clsoed"); }; sh.Open(); Console.ReadLine(); //pause sh.Close(); Console.ReadLine(); } } } [ServiceContract] public interface IService { [OperationContract] string Test(); } public class MyService : IService { public string Test() { return DateTime.Now.ToLongTimeString(); } }
Client-side (Core-based Console application with WcfCoreMtomEncoder nuget package, calling the service by using ChannelFactory).
class Program { static void Main(string[] args) { var encoding = new MtomMessageEncoderBindingElement(new TextMessageEncodingBindingElement()); var transport = new HttpTransportBindingElement(); transport.TransferMode = TransferMode.Streamed; var binding = new CustomBinding(encoding, transport); EndpointAddress endpoint = new EndpointAddress("http://vabqia969vm:21011"); ChannelFactory<IService> channelFactory = new ChannelFactory<IService>(binding, endpoint); var webService = channelFactory.CreateChannel(); Console.WriteLine(webService.Test()); } } [ServiceContract] public interface IService { [OperationContract] string Test(); }
One more thing we pay attention to is that we should manually bind a certificate to the particular port on the server-side if the server using Transport security mode to secure the communication.
Netsh http add sslcert ipport=0.0.0.0 certhash=0102030405060708090A0B0C0D0E0F1011121314 appid={00112233-4455-6677-8899-AABBCCDDEEFF}
In the above example, I bind a certificate that has a named vabqia969vm subject(DNS) to the machine(hostname is vabqia969vm). Here are some official links.
https://learn.microsoft.com/en-us/windows/win32/http/add-sslcert
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-a-port-with-an-ssl-certificate
On the client-side, before making a call to the service, we should establish a trust relationship so that communication is available between the client-side and the server-side. Therefore, I install the server certificate on the client-side LocalCA(Trusted Root Certification Authorities in the certification store). Alternatively, we could manually add a certificate validation process.
ChannelFactory<IService> channelFactory = new ChannelFactory<IService>(binding, endpoint); channelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = new System.ServiceModel.Security.X509ServiceCertificateAuthentication() { CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None, RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck };
Feel free to let me know if there is anything I can help with.
Updated.
I have updated the above example which works properly over HTTP protocol.