2014-09-29 6 views
3

콘솔 응용 프로그램에서 SOAP 서비스 용 클라이언트를 사용하고 있으며 SharePoint 2010으로 서비스 클라이언트를 이동해야합니다. 구성 파일 배포 및 기타 셰어 포인트 관련 작업을 원하지 않기 때문에 바인딩 정보를 하드 코드하기로 결정한 유일한 구성 가능한 옵션은 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); 

이 그것은 예상 작품과 같이

<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> 
은 또한, 나는이 코드를 가지고 : 나는 설정을 가지고있다. 지금은 XML 설정의 없애과 completly 코드로 이동하려면 :

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

그것은 서버에 도달하지만, 예외를 ("서버 오류"발생), 그래서 나는 나의 구성에 잘못된 점을 알았다. 독자 쿼터도 지정할 수 없습니다. 내가로드 configuration from string 시도했지만, 나를 위해, 같은 오류가 작동하지 않습니다. Confi 사용자 지정 바인딩을 XML에서 .net 3.5 코드로 변환 할 수없는 것 같습니다. 누군가 내 코드를보고 확인해 줄 수 있습니까? 코드에서 사용자 정의 바인딩을 사용하여 서비스 클라이언트를 가질 수있는 다른 방법이 있습니까?

+0

당신은 리더 할당량을 지정하려고 할 때 어떻게됩니까? 또한 이벤트 뷰어에서 오류에 대한 정보가 있는지 확인 했습니까? – Tim

+0

.net 4.5에서 동일한 쿼터를 지정하려고했습니다. 서버의 이벤트 뷰어를 의미합니까? 불행하게도 그것은 SAP 서비스이며 그 환경에 대한 액세스 권한이 없습니다. – boades

답변

5

app.config에서 사용자 정의 바인딩 코드로 구성을 이동하는 방법을 찾지 못했습니다.이 코드는 basicHttpBinding에 대한 greate를 작동하지만 customBinding에는 작동하지 않습니다.

사용자 정의 채널 팩토리를 사용하여 파일에서 구성 동력을로드하는 작업이 끝났습니다.

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

유용한 링크 : 당신이 전송 바인딩을 혼합 한 경우

1

이 boades에서 참조 코드에 문제가 있다는 점에서, 응답 발견 (https/http) 비슷한 예외이의/역 얻을 가능성이 basicHttpbinding 아래 :

제공되는 URI 방식 '은 https'가 잘못되었습니다; 예상 된 'http'. 매개 변수 이름 :

를 통해 나 또한 당신은 또한 예상치 못한 인증 코드가 web.config보다는 이름이 나열된 첫 번째 bindingConfiguration를 사용합니다 다시로서, 발생하는 것 기대.

이름으로 바인딩을 취할 것이 아니라 단지 1 일 소요되지 않는 문제가되는 라인 (!)

는 = bindingElementCollection 수 IBindingConfigurationElement.ConfiguredBindings [0];

CreateBinding 방법 등과 같은 CreateDescription에서 전화를 업데이트하여 수정 될 수있다 :

protected override ServiceEndpoint CreateDescription() 
{ 
    ServiceEndpoint description = base.CreateDescription(); 
    if (CustomisedChannelFactory<TChannel>.ConfigurationPath == null || !System.IO.File.Exists(CustomisedChannelFactory<TChannel>.ConfigurationPath)) 
     return base.CreateDescription(); 
    ServiceModelSectionGroup sectionGroup = ServiceModelSectionGroup.GetSectionGroup(ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap() 
    { 
     ExeConfigFilename = CustomisedChannelFactory<TChannel>.ConfigurationPath 
    }, ConfigurationUserLevel.None)); 
    ChannelEndpointElement channelEndpointElement1 = (ChannelEndpointElement)null; 
    foreach (ChannelEndpointElement channelEndpointElement2 in (ConfigurationElementCollection)sectionGroup.Client.Endpoints) 
    { 
     if (channelEndpointElement2.Contract == description.Contract.ConfigurationName) 
     { 
      channelEndpointElement1 = channelEndpointElement2; 
      break; 
     } 
    } 
    if (channelEndpointElement1 != null) 
    { 
     if (description.Binding == null) 
      description.Binding = this.CreateBinding(channelEndpointElement1.Binding, channelEndpointElement1.BindingConfiguration, sectionGroup); 
     if (description.Address == (EndpointAddress)null) 
      description.Address = new EndpointAddress(channelEndpointElement1.Address, this.GetIdentity(channelEndpointElement1.Identity), channelEndpointElement1.Headers.Headers); 
     if (description.Behaviors.Count == 0 && !string.IsNullOrEmpty(channelEndpointElement1.BehaviorConfiguration)) 
      this.AddBehaviors(channelEndpointElement1.BehaviorConfiguration, description, sectionGroup); 
     description.Name = channelEndpointElement1.Contract; 
    } 
    return description; 
} 

private Binding CreateBinding(string bindingName, string bindingConfigurationName, ServiceModelSectionGroup group) 
{ 
    BindingCollectionElement collectionElement = group.Bindings[bindingName]; 
    if (collectionElement.ConfiguredBindings.Count <= 0) 
     return (Binding)null; 

    IBindingConfigurationElement configurationElement = null; 
    foreach (IBindingConfigurationElement bce in collectionElement.ConfiguredBindings) 
    { 
     if (bce.Name.Equals(bindingConfigurationName)) 
     { 
      configurationElement = bce; 
      break; 
     } 
    } 
    if (configurationElement == null) throw new Exception("BindingConfiguration " + bindingConfigurationName + " not found under binding " + bindingName); 

    Binding binding = this.GetBinding(configurationElement); 
    if (configurationElement != null) 
     configurationElement.ApplyConfiguration(binding); 
    return binding; 
}