2012-04-17 3 views
1

프로그래밍 방식으로 구성된 WCF 클라이언트 (System.ServiceModel.ClientBase)로 작업하고 있습니다. 이 WCF 클라이언트는 기본적으로 TextMessageEncodingBindingElement가있는 CustomBinding을 사용하여 구성됩니다.WCF System.ServiceModel.ClientBase의 Endpoint.Binding 변경이 작동하지 않습니다.

이제 Mtom 인코딩으로 전환하려고 할 때 클라이언트의 Endpoint.Binding 속성을 변경하여 올바르게 작동합니다. Endpoint.Binding 속성 show가 변경되었습니다.

불행히도 WCF 서비스가 노출하는 메서드 중 하나를 실행하면 여전히 TextMessageEncoding이 사용되며 그 이유를 파악할 수 없습니다.

나는 그것이 새로운 ClientBase을 구성하고 생성자에서 새로운 EndPointBinding를 전달하여,하지만 일이있어 :

socialProxy = new SocialProxyClient(SocialProxyClientSettings.SocialProxyMTomEndPointBinding, new EndpointAddress(SocialProxyClientSettings.SocialProxyEndPointAddress)); 

하지만이 때 작동하지 않습니다

socialProxy.Endpoint.Binding = SocialProxyClientSettings.SocialProxyMTomEndPointBinding; 

이 나의 정의는 EndPointBindings위한 것입니다 :

public static TextMessageEncodingBindingElement TextMessageEncodingBindingElement 
{ 
    get 
    { 
     if (_textMessageEncodingBindingElement == null) 
     { 
      _textMessageEncodingBindingElement = new TextMessageEncodingBindingElement() { MessageVersion = MessageVersion.Soap11 }; 
      _textMessageEncodingBindingElement.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas() 
      { 
       MaxDepth = 32, 
       MaxStringContentLength = 5242880, 
       MaxArrayLength = 204800000, 
       MaxBytesPerRead = 5242880, 
       MaxNameTableCharCount = 5242880 
      }; 
     } 
     return _textMessageEncodingBindingElement; 
    } 
} 

public static MtomMessageEncodingBindingElement MtomMessageEncodingBindingElement 
{ 
    get 
    { 
     if (_mtomMessageEncodingBindingElement == null) 
     { 
      _mtomMessageEncodingBindingElement = new MtomMessageEncodingBindingElement(); 
      _mtomMessageEncodingBindingElement.MaxReadPoolSize = TextMessageEncodingBindingElement.MaxReadPoolSize; 
      _mtomMessageEncodingBindingElement.MaxWritePoolSize = TextMessageEncodingBindingElement.MaxWritePoolSize; 
      _mtomMessageEncodingBindingElement.MessageVersion = TextMessageEncodingBindingElement.MessageVersion; 
      _mtomMessageEncodingBindingElement.ReaderQuotas.MaxDepth = TextMessageEncodingBindingElement.ReaderQuotas.MaxDepth; 
      _mtomMessageEncodingBindingElement.ReaderQuotas.MaxStringContentLength = TextMessageEncodingBindingElement.ReaderQuotas.MaxStringContentLength; 
      _mtomMessageEncodingBindingElement.ReaderQuotas.MaxArrayLength = TextMessageEncodingBindingElement.ReaderQuotas.MaxArrayLength; 
      _mtomMessageEncodingBindingElement.ReaderQuotas.MaxBytesPerRead = TextMessageEncodingBindingElement.ReaderQuotas.MaxBytesPerRead; 
      _mtomMessageEncodingBindingElement.ReaderQuotas.MaxNameTableCharCount = TextMessageEncodingBindingElement.ReaderQuotas.MaxNameTableCharCount; 
     } 
     return _mtomMessageEncodingBindingElement; 
    } 
} 

사람이 왜 장을 설명 할 수 Endpoint.Binding 프로그래밍 방식으로 작동하지 않는다?

답변

2

나는 ClientBase를 구성하는 동안 원래의 Binding이 일부 도우미 객체를 만드는 데 사용된다고 생각합니다. 나중에 바인딩을 변경해도 해당 도우미 객체는 변경되지 않습니다.

구성 후 조정하려면 사용자 지정 바인딩 동작이 필요할 수 있으므로 필요에 따라 바인딩의 내부를 조정할 수 있습니다. 모든 도우미 객체가 나중에 변경 될 수 있도록 준비되어 있으므로이를 사용하십시오. 늘 그렇듯이, 간단한 행동 변경 하나만 있으면되지만, 한 가지 행동 변화를 지원하기 위해서는 보조 헬퍼 클래스도 작성해야합니다.

SO 스레드를 참조하십시오. ONVIF Authentication in .NET 4.0 with Visual Studio 2010 CustomBinding 문제에 대한 설명은 다음을 참조하십시오.

블로그 게시물보기 Supporting the WS-I Basic Profile Password Digest in a WCF Client Proxy 사용자 이름 토큰을 즉시 변경할 수있는 사용자 지정 동작의 예를 보려면

아마도 로컬 엔드 포인트 바인딩을 제어 할 수 있도록 비슷한 기능을 수행 할 수 있습니다.

업데이트 : 여기 StackOverflow에서 더 많은 독서가 있고 페이지가 링크되어 있으며 내가 찾고있는 답변을 찾은 것 같습니다.

PasswordDigestBehavior를 들어

: 은 다음을 참조하십시오 ONVIF Authentication in .NET 4.0 with Visual Studios 2010 과 : 지역 NIC를 들어 http://benpowell.org/supporting-the-ws-i-basic-profile-password-digest-in-a-wcf-client-proxy/

바인딩 : 참조 : Specify the outgoing IP address to use with WCF client

// ASSUMPTIONS: 
// 1: DeviceClient is generated by svcutil from your WSDL. 
// 1.1: DeviceClient is derived from 
//   System.ServiceModel.ClientBase<Your.Wsdl.Device> 
// 2: serviceAddress is the Uri provided for your service. 
// 
private static DeviceClient CreateDeviceClient(IPAddress nicAddress, 
               Uri serviceAddress, 
               String username, 
               String password) 
{ 
    if (null == serviceAddress) 
     throw new ArgumentNullException("serviceAddress"); 

    ////////////////////////////////////////////////////////////////////////////// 
    // I didn't know how to put a variable set of credentials into a static 
    // app.config file. 
    // But I found this article that talks about how to set up the right kind 
    // of binding on the fly. 
    // I also found the implementation of PasswordDigestBehavior to get it all to work. 
    // 
    // from: https://stackoverflow.com/questions/5638247/onvif-authentication-in-net-4-0-with-visual-studios-2010 
    // see: http://benpowell.org/supporting-the-ws-i-basic-profile-password-digest-in-a-wcf-client-proxy/ 
    // 
    EndpointAddress serviceEndpointAddress = new EndpointAddress(serviceAddress); 
    HttpTransportBindingElement httpBinding = new HttpTransportBindingElement(); 
    if (!String.IsNullOrEmpty(username)) 
    { 
     httpBinding.AuthenticationScheme = AuthenticationSchemes.Digest; 
    } 
    else 
    { 
     httpBinding.AuthenticationScheme = AuthenticationSchemes.Anonymous; 
    } 
    var messageElement = new TextMessageEncodingBindingElement(); 
    messageElement.MessageVersion = 
     MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None); 

    CustomBinding bind = new CustomBinding(messageElement, httpBinding); 

    //////////////////////////////////////////////////////////////////////////////// 
    // from: https://stackoverflow.com/questions/3249846/specify-the-outgoing-ip-address-to-use-with-wcf-client 
    // Adjust the serviceEndpointAddress to bind to the local NIC, if at all possible. 
    // 
    ServicePoint sPoint = ServicePointManager.FindServicePoint(serviceAddress); 
    sPoint.BindIPEndPointDelegate = delegate(
      System.Net.ServicePoint servicePoint, 
      System.Net.IPEndPoint remoteEndPoint, 
      int retryCount) 
    { 
     // if we know our NIC local address, use it 
     // 
     if ((null != nicAddress) 
      && (nicAddress.AddressFamily == remoteEndPoint.AddressFamily)) 
     { 
      return new System.Net.IPEndPoint(nicAddress, 0); 
     } 
     else if (System.Net.Sockets.AddressFamily.InterNetworkV6 == remoteEndPoint.AddressFamily) 
     { 
      return new System.Net.IPEndPoint(System.Net.IPAddress.IPv6Any, 0); 
     } 
     else // if (System.Net.Sockets.AddressFamily.InterNetwork == remoteEndPoint.AddressFamily) 
     { 
      return new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0); 
     } 
    }; 
    ///////////////////////////////////////////////////////////////////////////// 

    DeviceClient client = new DeviceClient(bind, serviceEndpointAddress); 

    // Add our custom behavior 
    // - this requires the Microsoft WSE 3.0 SDK file: Microsoft.Web.Services3.dll 
    // 
    PasswordDigestBehavior behavior = new PasswordDigestBehavior(username, password); 
    client.Endpoint.Behaviors.Add(behavior); 

    return client; 
} 
+0

@Junto - 감사합니다. –