这两个代码应该是等价的?以编程方式设置端点

This two codes should be equivalent? Setting Endpoint programmatically

我正在使用非我公司提供的 WCF 服务。

我需要在代码中进行 WCF 设置(无 .config 文件修改)。

考虑到这一点,我尝试在一个普通项目中使用一种方法,该方法具有 Web.config(由 Add Service Reference 生成)中的设置以首先进行测试。它确实有效。

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IIntegracao" />
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://wcf.mydomain.com.br/Integracao.svc/Integracao.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IIntegracao"
            contract="ServiceReference1.IIntegracao" name="WSHttpBinding_IIntegracao">
            <identity>
                <userPrincipalName value="user@mydomain.com.br" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

我这样称呼它:

using (var client = new ServiceReference1.IntegracaoClient())
{
    var resultado = client.Incluir(new Inclusao());
}

我继续我的任务,删除了 Web.config 中的所有设置,但无法使其正常工作。

我什至试图让 Web.config 保持不变,只是在客户端构造函数中这样通知它:

string url = ConfigurationManager.AppSettings["same url as above"];

var client2 = new IntegracaoClient(
            "WSHttpBinding_IIntegracao",
            new EndpointAddress(url));

var resultado2 = client2.Incluir(new Inclusao());

没用

System.ServiceModel.Security.SecurityNegotiationException was unhandled HResult=-2146233087 Message=SOAP security negotiation with 'http://wcf.mydomain.com.br/Integracao.svc/Integracao.svc' for target 'http://wcf.mydomain.com.br/Integracao.svc/Integracao.svc' failed. See inner exception for more details.

InnerException: System.ComponentModel.Win32Exception HResult=-2147467259 Message=Security Support Provider Interface (SSPI) authentication failed. The server may not be running in an account with identity 'host/wcf.mydomain.com.br'. If the server is running in a service account (Network Service for example), specify the account's ServicePrincipalName as the identity in the EndpointAddress for the server. If the server is running in a user account, specify the account's UserPrincipalName as the identity in the EndpointAddress for the server. Source=System.ServiceModel

我的问题是:第二次调用是否等同于第一次调用?

据我所知,第二次调用要求客户端使用与第一次调用相同的配置。为什么第二个失败了?

不,它们不等价。在配置中,您将端点身份设置为某个用户,在代码中您不这样做。

ServiceEndpoint ep = myServiceHost.AddServiceEndpoint(
                typeof(ICalculator),
                new WSHttpBinding(),
                String.Empty);
EndpointAddress myEndpointAdd = new EndpointAddress(new Uri("http://localhost:8088/calc"),
     EndpointIdentity.CreateDnsIdentity("contoso.com"));
ep.Address = myEndpointAdd;

看看: https://msdn.microsoft.com/en-us/library/bb628618.aspx Programmatically set identity on WCF EndpointAddress

@Jocke 发布 hist 答案后,我详细说明并找到了解决方案。

就像他说的那样,配置在 config 中有 Identity,但是在代码中设置时,应该处理它的是地址。

由于找不到他所说的相同构造函数,我需要进行一些更改以使其适合我的代码(框架 4):

var endpoint = new EndpointAddress(
    new Uri(ConfigurationManager.AppSettings["same url as above"]),
    EndpointIdentity.CreateUpnIdentity("user@domain.com.br"),
    (System.ServiceModel.Channels.AddressHeaderCollection)null);

var client3 = new ServiceReference1.IntegracaoClient(
    new WSHttpBinding(),
    endpoint);

最后一个构造函数参数转换 null 只是为了向编译器澄清我想要的重载。我用 CreateUpnIdentity 代替。