将Web服务配置转换为代码

 mysrain3 发布于 2022-12-19 11:45

我在控制台应用程序中有一个SOAP服务客户端,我需要将服务客户端移动到sharepoint 2010.我不想做配置文件部署和其他与sharepoint相关的东西,所以我决定硬编码绑定信息,唯一可配置的选项是URL.但是我在这方面遇到了一些麻烦.我有一个配置:

    

  
    
      
        
      
      
    
  


  

另外,我有一个代码:

    var service = new ServiceClient();
    service.ClientCredentials.Windows.ClientCredential = new NetworkCredential("user", "password");
    service.ClientCredentials.UserName.UserName = "user";
    service.ClientCredentials.UserName.Password = "password";

    var resp = service.Operation();
    Console.WriteLine(resp.Response);

它按预期工作.现在我想摆脱xml配置并完全将其移动到代码:

public class CustomHttpTransportBinding : CustomBinding
{
    public CustomHttpTransportBinding()
    {
    }

    public override BindingElementCollection CreateBindingElements()
    {
        var result = new BindingElementCollection();
        result.Add(new TextMessageEncodingBindingElement
        {
            MaxReadPoolSize = 64,
            MaxWritePoolSize = 16,
            MessageVersion = MessageVersion.Soap11,
            WriteEncoding = Encoding.UTF8,

            //ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas
            //{
            //    MaxDepth = 10000000,
            //    MaxStringContentLength = 10000000,
            //    MaxArrayLength = 67108864,
            //    MaxBytesPerRead = 65536,
            //    MaxNameTableCharCount = 100000
            //}
        });

        result.Add(new HttpTransportBindingElement
        {
            AuthenticationScheme = AuthenticationSchemes.Basic,
            BypassProxyOnLocal = false,
            HostNameComparisonMode = System.ServiceModel.HostNameComparisonMode.StrongWildcard,
            KeepAliveEnabled = false,
            ProxyAuthenticationScheme = AuthenticationSchemes.Basic,
            Realm = "XISOAPApps",
            UseDefaultWebProxy = true
        });

        return result;
    }
}

我这样使用它:

    var service = new ServiceClient(new CustomHttpTransportBinding(), new EndpointAddress(url));
    service.ClientCredentials.Windows.ClientCredential = new NetworkCredential("user", "password");
    service.ClientCredentials.UserName.UserName = "user";
    service.ClientCredentials.UserName.Password = "password";

    var resp = service.Operation();
    Console.WriteLine(resp.Response);

它到达服务器,但抛出异常("服务器错误"),所以我认为我的配置有问题.我也无法指定读者配额.我已经尝试从字符串加载配置,但它不适合我,同样的错误.Confi似乎我无法将自定义绑定从XML转换为.net 3.5中的代码.有人可以查看我的代码并确认吗?是否有其他方法可以在代码中使用自定义绑定的服务客户端?

1 个回答
  • 我还没有找到一种方法将配置从app.config移动到自定义绑定的代码,它对basicHttpBinding有效,但不适用于customBinding.

    我最终使用自定义chanell工厂从文件加载动态配置.

    public class CustomChannelFactory<T> : ChannelFactory<T>
    {
        private readonly string _configurationPath;
    
        public CustomChannelFactory(string configurationPath) : base(typeof(T))
        {
            _configurationPath = configurationPath;
            base.InitializeEndpoint((string)null, null);
        }
    
        protected override ServiceEndpoint CreateDescription()
        {
            ServiceEndpoint serviceEndpoint = base.CreateDescription();
    
            ExeConfigurationFileMap executionFileMap = new ExeConfigurationFileMap();
            executionFileMap.ExeConfigFilename = _configurationPath;
    
            System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(executionFileMap, ConfigurationUserLevel.None);
            ServiceModelSectionGroup serviceModeGroup = ServiceModelSectionGroup.GetSectionGroup(config);
    
            ChannelEndpointElement selectedEndpoint = null;
            foreach (ChannelEndpointElement endpoint in serviceModeGroup.Client.Endpoints)
            {
                if (endpoint.Contract == serviceEndpoint.Contract.ConfigurationName)
                {
                    selectedEndpoint = endpoint;
                    break;
                }
            }
    
            if (selectedEndpoint != null)
            {
                if (serviceEndpoint.Binding == null)
                {
                    serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, serviceModeGroup);
                }
    
                if (serviceEndpoint.Address == null)
                {
                    serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address, GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);
                }
    
                if (serviceEndpoint.Behaviors.Count == 0 && !String.IsNullOrEmpty(selectedEndpoint.BehaviorConfiguration))
                {
                    AddBehaviors(selectedEndpoint.BehaviorConfiguration, serviceEndpoint, serviceModeGroup);
                }
    
                serviceEndpoint.Name = selectedEndpoint.Contract;
            }
    
            return serviceEndpoint;
        }
    
        private Binding CreateBinding(string bindingName, ServiceModelSectionGroup group)
        {
            BindingCollectionElement bindingElementCollection = group.Bindings[bindingName];
            if (bindingElementCollection.ConfiguredBindings.Count > 0)
            {
                IBindingConfigurationElement be = bindingElementCollection.ConfiguredBindings[0];
    
                Binding binding = GetBinding(be);
                if (be != null)
                {
                    be.ApplyConfiguration(binding);
                }
    
                return binding;
            }
    
            return null;
        }
    
        private void AddBehaviors(string behaviorConfiguration, ServiceEndpoint serviceEndpoint, ServiceModelSectionGroup group)
        {
            EndpointBehaviorElement behaviorElement = group.Behaviors.EndpointBehaviors[behaviorConfiguration];
            for (int i = 0; i < behaviorElement.Count; i++)
            {
                BehaviorExtensionElement behaviorExtension = behaviorElement[i];
                object extension = behaviorExtension.GetType().InvokeMember("CreateBehavior",
                BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
                null, behaviorExtension, null);
                if (extension != null)
                {
                    serviceEndpoint.Behaviors.Add((IEndpointBehavior)extension);
                }
            }
        }
    
        private EndpointIdentity GetIdentity(IdentityElement element)
        {
            EndpointIdentity identity = null;
            PropertyInformationCollection properties = element.ElementInformation.Properties;
            if (properties["userPrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
            {
                return EndpointIdentity.CreateUpnIdentity(element.UserPrincipalName.Value);
            }
            if (properties["servicePrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
            {
                return EndpointIdentity.CreateSpnIdentity(element.ServicePrincipalName.Value);
            }
            if (properties["dns"].ValueOrigin != PropertyValueOrigin.Default)
            {
                return EndpointIdentity.CreateDnsIdentity(element.Dns.Value);
            }
            if (properties["rsa"].ValueOrigin != PropertyValueOrigin.Default)
            {
                return EndpointIdentity.CreateRsaIdentity(element.Rsa.Value);
            }
            if (properties["certificate"].ValueOrigin != PropertyValueOrigin.Default)
            {
                X509Certificate2Collection supportingCertificates = new X509Certificate2Collection();
                supportingCertificates.Import(Convert.FromBase64String(element.Certificate.EncodedValue));
                if (supportingCertificates.Count == 0)
                {
                    throw new InvalidOperationException("UnableToLoadCertificateIdentity");
                }
                X509Certificate2 primaryCertificate = supportingCertificates[0];
                supportingCertificates.RemoveAt(0);
                return EndpointIdentity.CreateX509CertificateIdentity(primaryCertificate, supportingCertificates);
            }
    
            return identity;
        }
    
        private Binding GetBinding(IBindingConfigurationElement configurationElement)
        {
            if (configurationElement is CustomBindingElement)
                return new CustomBinding();
            else if (configurationElement is BasicHttpBindingElement)
                return new BasicHttpBinding();
            else if (configurationElement is NetMsmqBindingElement)
                return new NetMsmqBinding();
            else if (configurationElement is NetNamedPipeBindingElement)
                return new NetNamedPipeBinding();
            else if (configurationElement is NetPeerTcpBindingElement)
                return new NetPeerTcpBinding();
            else if (configurationElement is NetTcpBindingElement)
                return new NetTcpBinding();
            else if (configurationElement is WSDualHttpBindingElement)
                return new WSDualHttpBinding();
            else if (configurationElement is WSHttpBindingElement)
                return new WSHttpBinding();
            else if (configurationElement is WSFederationHttpBindingElement)
                return new WSFederationHttpBinding();
    
            return null;
        }
    }
    

    有用的链接:

    从不同文件加载WCF配置(源代码不可用)

    具有CustomChannelFactory源代码的线程

    .NET 4.0 ChanellFactory(希望它在.net 3.5中)

    2022-12-19 11:49 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有