You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用唯一ListenUri与WCF发现时出现To和Via URI必须匹配错误

解决BasicHttpBinding下To和Via URI必须相同的错误

这个错误的根源很明确:你使用的BasicHttpBinding默认采用AddressingVersion.None(不支持WS-Addressing规范),这种绑定要求请求的目标地址(To)和路由地址(Via)必须完全一致。而你设置了ListenUriMode.Unique让服务生成了唯一的监听Uri,客户端又通过ClientViaBehavior指定了这个监听Uri作为Via,同时保留原服务地址作为To,这就触发了绑定的限制条件。

下面给你两种可行的解决方案,根据你的需求选择:

方案一:改用支持WS-Addressing的绑定(推荐)

如果你的场景允许,换成WSHttpBinding(默认支持WS-Addressing),这样就能支持To和Via不同的情况,同时满足你设置ListenUriMode.Unique和保护级别为None的需求。

服务端代码修改:

Uri baseAddress = new Uri("http://localhost/" + Guid.NewGuid().ToString() + "/");
ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress);
try
{
    // 创建WSHttpBinding并设置安全模式为None(匹配保护级别要求)
    var binding = new WSHttpBinding(SecurityMode.None);
    binding.Security.Message.ClientCredentialType = MessageCredentialType.None;
    binding.Security.Message.EstablishSecurityContext = false;
    
    ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(typeof(ICalculatorService), binding, string.Empty);
    endpoint.ListenUriMode = ListenUriMode.Unique;
    
    serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
    serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
    serviceHost.Open();
    Console.WriteLine("Calculator Service started at {0}", baseAddress);
    Console.ReadLine();
}
catch (CommunicationException e)
{
    Console.WriteLine(e.Message);
}

客户端InvokeCalculatorService方法修改:

// 改用WSHttpBinding匹配服务端
CalculatorServiceClient client = new CalculatorServiceClient(new WSHttpBinding(SecurityMode.None), endpointAddress);
Console.WriteLine("Invoking CalculatorService at {0}", endpointAddress.Uri);
if (viaUri != null)
{
    client.Endpoint.Behaviors.Add(new ClientViaBehavior(viaUri));
    Console.WriteLine("Using the viaUri {0}", viaUri);
}
// 后续调用逻辑不变...

方案二:继续使用BasicHttpBinding,直接用ListenUri作为目标地址

如果必须保留BasicHttpBinding,那就要放弃ClientViaBehavior,直接将服务的监听Uri作为客户端请求的目标地址(To),这样To和Via就会自动一致。

客户端代码修改:

if (findResponse.Endpoints.Count > 0)
{
    EndpointDiscoveryMetadata discoveredEndpoint = findResponse.Endpoints[0];
    if (discoveredEndpoint.ListenUris.Count > 0 && discoveredEndpoint.Address.Uri != discoveredEndpoint.ListenUris[0])
    {
        // 直接用ListenUri创建EndpointAddress,不再使用ClientViaBehavior
        InvokeCalculatorService(new EndpointAddress(discoveredEndpoint.ListenUris[0]), null);
    }
    else
    {
        InvokeCalculatorService(discoveredEndpoint.Address, null);
    }
}

这样修改后,客户端请求的目标地址就是服务实际监听的Uri,完全符合BasicHttpBinding的要求,错误就会消失。


内容的提问来源于stack exchange,提问作者A.Learn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:40:18