转换Web服务配置为code [英] Convert web service configuration to code

查看:256
本文介绍了转换Web服务配置为code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对SOAP服务的客户端在控制台应用程序,我需要移动服务客户端到SharePoint 2010。我不想做配置文件的部署和其他SharePoint相关的东西,所以我决定硬code语言绑定信息,唯一的配置选项就是网址。但我encountred一些麻烦这样做。我有一个配置:

I have a client for SOAP service in a console application, I need to move the service client to sharepoint 2010. I do not want to do config files deployment and other sharepoint-related stuff, so I decided to hardcode binding information, the only configurable option is URL. But I encountred some troubles doing this. I have a config:

    <system.serviceModel>
<bindings>
  <customBinding>
    <binding name="SI_PMProjectMaintain_SOUTBinding">
      <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
        messageVersion="Soap11" writeEncoding="utf-8">
        <readerQuotas maxDepth="10000000" maxStringContentLength="10000000"
          maxArrayLength="67108864" maxBytesPerRead="65536" maxNameTableCharCount="100000" />
      </textMessageEncoding>
      <httpTransport authenticationScheme="Basic" bypassProxyOnLocal="false"
        hostNameComparisonMode="StrongWildcard" keepAliveEnabled="false"
        proxyAuthenticationScheme="Basic" realm="XISOAPApps" useDefaultWebProxy="true" />
    </binding>
  </customBinding>
</bindings>
<client>
  <endpoint address="http://url/XISOAPAdapter/MessageServlet?senderParty=&amp;senderService=Param1&amp;receiverParty=&amp;receiverService=&amp;interface=interface&amp;interfaceNamespace=url"
    binding="customBinding" bindingConfiguration="SI_PMProjectMaintain_SOUTBinding"
    contract="PmProjectMaintain.SI_PMProjectMaintain_SOUT" name="HTTP_Port" />
</client>

另外,我有一个code:

Also, I have a code:

    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配置和完全地将其移动到code:

It works as expected. Now I want to get rid of xml config and completly move it to code:

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

它到达服务器,但抛出的异常(服务器错误),所以我相信有毛病我的配置。我不能指定读者配额也。我已经试过装<一href="http://blogs.msdn.com/b/jimmytr/archive/2011/02/15/snippet-construct-wcf-binding-from-string-xml.aspx"相对=nofollow>从字符串的配置,但它不是为我工作,同样的错误。 CONFI 看来我无法从XML转换自定义绑定至code在.NET 3.5中。有人可以承担我的code一看,确认?有没有其他的方式来与在code定义绑定服务客户端?

It reaches the server, but throws exception ("Server Error"), so I belive something wrong with my configuration. I can not specify the reader quotas also. I've tried loading configuration from string, but it is not worked for me, same error. Confi It seems that I can not convert custom bindings from XML to code in .net 3.5. Can somebody take a look on my code and confirm? Are there other ways to have a service client with custom binding in code?

推荐答案

我还没有找到一种方法,将配置从app.config中至code为自定义绑定,它的工作原理马丽娟为basicHttpBinding的,但不工作为customBinding。

I have not found a way to move configuration from app.config to code for a custom binding, it works greate for basicHttpBinding, but does not work for customBinding.

我已经结束了与文件中使用自定义chanell工厂dynamicaly加载配置。

I've ended up with loading the configuration dynamicaly from file using custom chanell factory.

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;
    }
}

有用的链接:

Usefull links:

  • <一个href="http://weblogs.asp.net/cibrax/loading-the-wcf-configuration-from-different-files-on-the-client-side">Loading从不同的文件(来源$ C ​​$ c不是availiable)
  • WCF配置
  • <一个href="http://social.msdn.microsoft.com/Forums/vstudio/en-US/f33e620a-e332-4fd4-ae21-88c750437355/config-hosting-multiple-wcf-services-in-one-nt-service?forum=wcf">Thread与源$ C ​​$ CustomChannelFactory了C
  • <一个href="http://blogs.msdn.com/b/youssefm/archive/2010/09/02/loading-wcf-client-configuration-from-different-files-with-configurationchannelfactory.aspx">.NET 4.0 ChanellFactory(希望这是在.NET 3.5中)
  • Loading WCF configuration from different files (source code is not availiable)
  • Thread with source code of CustomChannelFactory
  • .NET 4.0 ChanellFactory (wish it was in .net 3.5)

这篇关于转换Web服务配置为code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆