2017-06-02 196 views
0

我使用HttpTransportBindingElement與端口80上的IIS一起編碼了一個WCF服務。 只要沒有使用代理,代碼就可以正常工作。但是,如果客戶有一個http代理,WCF客戶端和服務器之間的通信在這種情況下通過發生以下錯誤不起作用:如何在WCF上使用HttpTransportBindingElement設置代理憑證?

'沒有端點正在聽......以接受該消息。這通常是由不正確的地址或SOAP操作引起的。「

只有通過代碼才能使用設置!

這是我對這個問題的代碼的做法,但我堅持就可以了:

bool SendClientRequest(Action<ICustomerService> channel) 
{ 

    string proxy ="my.proxy.domain:8080"; 
    string user = "user1"; 
    string password="secret"; 

    // maybe i do not need this 3 lines! 
    WebProxy webproxy = new WebProxy(proxy, true); 
    webproxy.Credentials = new NetworkCredential(user, password); 
    WebRequest.DefaultWebProxy = webproxy; 

    CustomBinding customBinding = new CustomBinding(); 
    customBinding.Elements.Add(new HttpTransportBindingElement() 
    { 

    AuthenticationSchemes.None : AuthenticationSchemes.Basic,     
    ProxyAddress = string.IsNullOrEmpty(proxy) ? null : new Uri(proxy), 
    UseDefaultWebProxy = false, 
    BypassProxyOnLocal = true, 
    TransferMode = TransferMode.Streamed, 
    MaxReceivedMessageSize = 84087406592, 
    MaxBufferPoolSize = 0x1000000, 
    MaxBufferSize = 0x1000000 

    }); 


    using (ChannelFactory<ICustomerService> factory = new 
    ChannelFactory<ICustomerService>(customBinding)) 
    { 
    IClientChannel contextChannel = null; 
    string url = "http://my.domain.de/Distribution/eService.svc", 
    EndpointAddress ep = new EndpointAddress(url); 
    ICustomerService clientChannel = factory.CreateChannel(ep);     


    contextChannel = clientChannel as IClientChannel; 
    contextChannel.OperationTimeout = TimeSpan.FromMinutes(rcvTimeout); 

    channel(clientChannel); // <- here i get the exception! 
    return true; 
    } 
} 

我嘗試了幾種解決方案,但似乎沒有什麼具體像我一樣。

回答

0

我想你有幾個選項,其中一些我會在下面詳細介紹。

首先,您可以將UseDefaultWebProxy設置爲true。這意味着代理信息會從系統代理設置中自動檢索,可在Internet Explorer中配置(Internet選項>連接> LAN設置>代理服務器)。如果您不需要指定代理使用的憑證,這可能是適當的。

另一種適用於我的方法是在HttpTransportBindingElement()對象內使用ProxyAuthenticationScheme屬性。此屬性僅在CustomBinding類中可用,並允許指定將用於對代理進行身份驗證的身份驗證方案。與此一起,代理服務器必須針對屬性ProxyAddress進行設置。最後但並非最不重要的,要使用的憑據針對應根據所使用的身份驗證方案來設置代理,因此,例如,使用AuthenticationSchemes.Ntlm將意味着設置用戶名和密碼屬性上ChannelFactory.ClientCredentials.Windows.ClientCredential或許ChannelFactory.ClientCredentials.HttpDigest.ClientCredential

在第二種方法中,請務必注意ChannelFactory中用於與遠程服務一起使用的憑證與用於代理服務器的憑證之間的區別。爲了清晰起見,我在下面的代碼示例中強調了這些內容:

// Example service call using a CustomBinding that is configured for client 
// authentication based on a user name and password sent as part of the message. 
var binding = new CustomBinding(); 

TransportSecurityBindingElement securityBindingElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement(); 

var secureTransport = new HttpsTransportBindingElement(); 
secureTransport.UseDefaultWebProxy = false; 
secureTransport.ProxyAddress = new Uri("http://some-proxy"); 
secureTransport.ProxyAuthenticationScheme = AuthenticationSchemes.Ntlm; 

binding.Elements.Add(securityBindingElement); 
binding.Elements.Add(secureTransport); 

var endpointAddress = new EndpointAddress("https://some-service"); 

var factory = new ChannelFactory<IService>(binding, endpointAddress); 

// Credentials for authentication against the remote service 
factory.Credentials.UserName.UserName = "serviceUser"; 
factory.Credentials.UserName.Password = "abc"; 

// Credentials for authentication against the proxy server 
factory.Credentials.Windows.ClientCredential.UserName = "domain\user"; 
factory.Credentials.Windows.ClientCredential.Password = "xyz"; 

var client = factory.CreateChannel(); 
client.CallMethod();