WCF如何在运行时更改终结点地址

43

我已经成功地实现了我的第一个WCF示例。我在一个具有多个绑定的网站上托管了主机。因此,我已将以下代码添加到我的web.config文件中:

<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>

这是我的默认绑定 http://id.web ,它与以下代码一起使用。

EchoServiceClient client = new EchoServiceClient();
litResponse.Text = client.SendEcho("Hello World");
client.Close();

我现在正在尝试在运行时设置端点地址,即使它与上面代码的地址相同。

EchoServiceClient client = new EchoServiceClient();
client.Endpoint.Address = new EndpointAddress("http://id.web/Services/EchoService.svc"); 

litResponse.Text = client.SendEcho("Hello World");
client.Close();

我遇到的错误是:

The request for security token could not be satisfied because authentication failed. 
请建议我如何在运行时更改终端节点地址? 以下是Ladislav Mrnka请求的我的客户端配置信息
 <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IEchoService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="None" />
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://id.web/Services/EchoService.svc" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IEchoService" contract="IEchoService"
                name="WSHttpBinding_IEchoService">
                <identity>
                    <servicePrincipalName value="host/mikev-ws" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>

你的客户端配置是什么样子? - Ladislav Mrnka
@Ladislav Mrnka:我已经更新了我的帖子以显示客户端配置。谢谢。 - Valamas
5个回答

33

所以在您的第一个示例中定义的终结点地址是不完整的。您还必须根据客户端配置定义终结点身份。在代码中,您可以尝试这样做:

EndpointIdentity spn = EndpointIdentity.CreateSpnIdentity("host/mikev-ws");
var address = new EndpointAddress("http://id.web/Services/EchoService.svc", spn);   
var client = new EchoServiceClient(address); 
litResponse.Text = client.SendEcho("Hello World"); 
client.Close();

valamas的实际可用最终版本

EndpointIdentity spn = EndpointIdentity.CreateSpnIdentity("host/mikev-ws");
Uri uri = new Uri("http://id.web/Services/EchoService.svc");
var address = new EndpointAddress(uri, spn);
var client = new EchoServiceClient("WSHttpBinding_IEchoService", address);
client.SendEcho("Hello World");
client.Close(); 

我已根据你提供的示例和我现在遇到的错误修改了我的帖子以显示我使用的代码。谢谢。 - Valamas
@Valamas:你确定你没有意外更改通信的某个配置部分吗?如果你只调用最初的代码而不从代码中传递EndpointAddress会发生什么? - Ladislav Mrnka
现在它可以工作了。问题出在我与约翰·佩特拉克合作时添加的配置更改上。当我离开办公室一小时后,这种情况并没有得到改善。非常感谢您的帮助。完美,干杯 :) - Valamas
这对我非常有用。对于像我一样还需要传递凭据的其他人,您可以在client声明后立即添加以下行:`client.ClientCredentials.UserName.UserName = "myUsername"; client.ClientCredentials.UserName.Password = "myPassword";` - Tod Birdsall

23

这是一个我最近用于测试的简单示例。您需要确保服务器和客户端的安全设置相同。

var myBinding = new BasicHttpBinding();
myBinding.Security.Mode = BasicHttpSecurityMode.None;
var myEndpointAddress = new EndpointAddress("http://servername:8732/TestService/");
client = new ClientTest(myBinding, myEndpointAddress);
client.someCall();

在 web.config 文件中,我将 <security mode="None"> 进行了更改。我已经在原始帖子中附加了我的当前代码和错误信息。 - Valamas

16

应用程序配置

<client>
    <endpoint address="" binding="basicHttpBinding" 
    bindingConfiguration="LisansSoap" 
    contract="Lisans.LisansSoap" 
    name="LisansSoap" />
</client>

程序

 Lisans.LisansSoapClient test = new LisansSoapClient("LisansSoap",
                         "http://webservis.uzmanevi.com/Lisans/Lisans.asmx");

 MessageBox.Show(test.LisansKontrol("","",""));

2
这样做简单得多。我正在用它来进行AD WS。 - klaudyuxxx

9
我们将URL存储在数据库中,并在运行时加载它们。
public class ServiceClientFactory<TChannel> : ClientBase<TChannel> where TChannel : class
{
    public TChannel Create(string url)
    {
        this.Endpoint.Address = new EndpointAddress(new Uri(url));
        return this.Channel;
    }
}

实现

var client = new ServiceClientFactory<yourServiceChannelInterface>().Create(newUrl);

0
您可以创建一个EndpointAddress,并使用客户端实例来确定绑定。
        EndpointAddress a = new("http://localhost:50415/Service1.svc");
        Service1Client c = new(new Service1Client().Endpoint.Binding, a);
        string result = c.GetData(3);

如果您不介意两次初始化客户端


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接