【问题标题】:How can I set the security mode to transport in WcfCoreMtomEncoder library?如何在 WcfCoreMtomEncoder 库中将安全模式设置为传输?
【发布时间】:2020-01-22 01:06:39
【问题描述】:

我正在尝试将文档发送到 .Net Core 应用程序中的 Web 服务。但我了解到.Net Core 不支持“MTOM”

WSMessageEncoding.Mtom

所以我找到了这个WcfCoreMtomEncoder 库,并认为我可以让它工作!??也许不是……?

这是我在 .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();

这是我放入图书馆后的东西

        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();

但是我在创建频道时遇到了这个异常

提供的 URI 方案“https”无效;预期为“http”

根据这个SO link我需要将安全模式设置为传输

问题 - 如何在这个WcfCoreMtomEncoder 库中将安全模式设置为传输? 我查看了一些“HttpTransportBindingElement”属性,但并没有真正看到要设置的属性。

【问题讨论】:

    标签: c# wcf wcf-binding wcf-security wcfcoremtomencoder


    【解决方案1】:

    你是对的,它在基于核心的项目中很有用。
    关于错误细节,是因为调用服务时客户端和服务端的绑定和服务地址要一致。由于绑定使用传输层安全模式,客户端中的服务 URL 必须通过 Https 协议工作。实际上,托管这种服务(传输安全模式)时,我们应该提供一个Https绑定地址。在客户端,我们构建一个自定义绑定来使用服务。那么就可以通过Https协议与服务器通信了。
    为了在Https 协议上工作,我们可以使用HttpsTransportBindingElement。请参考以下代码段。

    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());
    

    但是,它不起作用,因为事实是服务器端和客户端之间的绑定不一致。我们应该创建一个具有相同绑定的 WCF 服务。
    服务器端(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();
            }
        }
    

    结果。

    相关文档。
    https://docs.microsoft.com/en-us/dotnet/framework/wcf/extending/custom-bindings
    如果有什么可以帮助的,请随时告诉我。

    【讨论】:

    • 嗨,亚伯拉罕。我有一些问题。 1. 当你说“我们应该创建一个具有相同绑定的 WCF 服务”时,如果我的一方(客户端)是 .Net Core 而服务器端(我们的客户)是.Net Framework,我可以这样做。我相信这是因为他们的文档使用 .Net Framework 代码来调用他们的服务。 2. 在您的第二个代码 sn-p 中,您使用“MtomMessageEncodingBindingElement”我相信这是针对 .Net 框架的,对吧?如果我是 .Net Core,我不应该使用我找到的第 3 方库中的“MtomMessageEncoderBindingElement”吗? 3. 与问题 2 相同,但针对“ServiceHost”?
    • 首先,服务器端必须基于Dotnet框架,因为WCF框架尚未在Dotnet核心中实现。我们无法在 Dotnet 核心项目中创建 WCF 服务。基于核心的客户端只是一个兼容的解决方法。许多功能尚未实现。 github.com/dotnet/wcf
    • 1.上述客户端代码基于 Dotnet Core,服务器端 WCF 以 Dotnet 框架为目标。如果我们在基于 Dotnetframework 的项目中调用该服务,它是原生支持的。 Dotnet 框架已经支持 MTOM 编码。 2. 是的,因为支持 MTOM 编码是 dotnet 框架的内置功能。这些代码 sn-ps 是一个 WCF 服务器,在 Dotnet Core 中是不可能实现的。 “相同的绑定”是指自定义绑定而不是基本的httpbinding。 3. AspDotCore中还没有实现WCF服务,“ServiceHost”也没有实现。
    • @user1186050 ,在上面的代码sn-ps中,我们也可以创建一个没有传输层安全模式的服务。它也可以在 Dotnet Core 应用程序中正确调用。这样的话,不需要指定`https'基地址,也不需要绑定证书,轻松搞定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2011-11-05
    • 2018-07-25
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    相关资源
    最近更新 更多