1

I'm trying to send documents to a web service in a .Net Core app. But I learned that .Net Core doesn't support 'MTOM'

WSMessageEncoding.Mtom

so I found this WcfCoreMtomEncoder library and thought I could make it work!?? Maybe not...?

Here is what I had before .Net Core

        BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
        var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport)
        { 
            MessageEncoding = WSMessageEncoding.Mtom,
            TransferMode = TransferMode.Streamed
        };
        EndpointAddress endpoint = new EndpointAddress(url);
        ChannelFactory<T> channelFactory = new ChannelFactory<T>(binding, endpoint);
        var webService = channelFactory.CreateChannel();

Here is what I have after I put in the library

        var encoding = new MtomMessageEncoderBindingElement(new TextMessageEncodingBindingElement());
        var transport = new HttpTransportBindingElement();
        transport.TransferMode = TransferMode.Streamed;
        var binding = new CustomBinding(encoding, transport);
        EndpointAddress endpoint = new EndpointAddress(url);
        ChannelFactory<T> channelFactory = new ChannelFactory<T>(binding, endpoint);
        var webService = channelFactory.CreateChannel();

but I'm getting this exception when I create the channel

The provided URI scheme 'https' is invalid; expected 'http'

according to this SO link I need to set the security mode to transport

QUESTION - how do I set the security mode to transport in this WcfCoreMtomEncoder library? I looked through some of the 'HttpTransportBindingElement' properties but didn't really see one to set.

chuckd
  • 13,460
  • 29
  • 152
  • 331

1 Answers1

-1

You are right, it is useful in the core-based project.
In regard to the error details, it due to the fact that the binding and the service address should be consistent between the client-side and the server-side when calling the service. the service Url in the client-side has to work over Https protocol since the binding use transport layer security mode. In fact, we should provide an Https binding address when hosting this kind of service(transport security mode). On the client-side, we construct a custom binding to consume the service. Then it is practicable to communicate with the server over Https protocol.
In order to work over Https protocol, we could use HttpsTransportBindingElement. Please refer to the below code segments.

var encoding = new MtomMessageEncoderBindingElement(new TextMessageEncodingBindingElement());
            var transport = new HttpsTransportBindingElement();
            transport.TransferMode = TransferMode.Streamed;
            var binding = new CustomBinding(encoding, transport);
            EndpointAddress endpoint = new EndpointAddress("https://vabqia969vm:21011");
            ChannelFactory<IService> channelFactory = new ChannelFactory<IService>(binding, endpoint);
            var webService = channelFactory.CreateChannel();
            Console.WriteLine(webService.Test());

However, it won’t work cause the fact is the binding between the server-side and the client-side isn’t consistent. We should create a WCF service with the same binding.
Server-side(Dotnet Framework4.7.2).

class Program
    {
        static void Main(string[] args)
        {
            Uri uri = new Uri("https://localhost:21011");
            MtomMessageEncodingBindingElement encoding = new MtomMessageEncodingBindingElement();
            var transport = new HttpsTransportBindingElement();
            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()
                    {
                        HttpsGetEnabled = true
                    };
                    sh.Description.Behaviors.Add(smb);
                }
                Binding mexbinding = MetadataExchangeBindings.CreateMexHttpsBinding();
                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();
        }
    }

Result.
enter image description here
Related documentation.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/custom-bindings
Feel free to let me know if there is anything I can help with.

Abraham Qian
  • 7,117
  • 1
  • 8
  • 22
  • Hi Abraham. I have a couple of questions. 1. When you say "We should create a WCF service with the same binding" can I do this if my side (client side) is .Net Core and the server side (our customer) is .Net Framework. Which I believe it is as their documentation uses .Net Framework code to call their service. 2. In your 2nd code snippet you use "MtomMessageEncodingBindingElement" I believe this is for .Net Framework, right? If I'm .Net Core shouldn't I be using "MtomMessageEncoderBindingElement" from the 3rd party library I found? 3. Same as question 2 but for "ServiceHost"? – chuckd Jan 23 '20 at 03:10
  • At first, the server-side must base on Dotnet framework because WCF framework has not yet been implemented in Dotnet core. We can’t create a WCF service in Dotnet core project. the Core-based client-side just is a compatible workaround. Many features have not implemented yet. https://github.com/dotnet/wcf – Abraham Qian Jan 23 '20 at 08:50
  • 1. The above client-side code based on Dotnet Core, and the server-side WCF targets on Dotnet framework. If we call the service in a Dotnetframework-based project, it is supported natively. Dotnet framework already supports MTOM encoding. 2. Yes, because supporting MTOM encoding is a built-in feature in dotnet framework. These code snippets is a WCF server, which can’t possibly achieve it in Dotnet Core. “Same binding” means Custom binding instead of basichttpbinding. 3. WCF service has not yet been implemented in AspDotCore, neither do “ServiceHost”. – Abraham Qian Jan 23 '20 at 08:50
  • @user1186050 , In the above code snippets, we can also create a service without transport layer security mode. and it can be called properly in the Dotnet Core application as well. If we do in this way, we needn't specify `https' base address, there is no need to bind a certificate, It will be easily finished. – Abraham Qian Jan 27 '20 at 01:41