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

WCF双工wsDualHttpBinding找不到引用contract的endpoint元素报错

WCF wsDualHttpBinding发布订阅模式客户端找不到endpoint报错

问题现象

基于WCF Duplex的wsDualHttpBinding实现发布-订阅模式的通知服务时,客户端执行订阅操作抛出如下错误:

在ServiceModel客户端配置节中找不到引用contract的endpoint元素。该问题可能是因为应用程序未找到对应配置文件,或是client节点下不存在匹配该contract的endpoint元素


现有配置与代码

客户端App.config配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_IRecipeTemplateService" />
                <binding name="Basic1" />
            </wsDualHttpBinding>
        </bindings>
        <client>            
            <endpoint address="http://172.18.26.14/CentralService/Services/NotificationService.svc"
                binding="wsDualHttpBinding" bindingConfiguration="Basic1"
                contract="CentralNotificationService.INotificationService"
                name="Basic1">
                <identity>
                    <servicePrincipalName value="host/myclienthost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

服务端Web.config配置

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1"/>
  </system.web>
  <connectionStrings>
    <add name="RecipeDB" providerName="MySql.Data.MySqlClient"
         connectionString="Server=localhost; Port=3306; Database=recipe_db; Uid=root; Pwd=root" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/>
    <providers>
      <provider invariantName="MySql.Data.MySqlClient"
          type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.EntityFramework"/>
      <provider invariantName="System.Data.SqlClient"
          type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="MySql.Data.MySqlClient" />
      <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL"
           type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=8.0.28.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </DbProviderFactories>
  </system.data>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="mexBehavior" name="RecipeServer.Central.Service.Services.NotificationService">
        <endpoint address="" binding="wsDualHttpBinding"
          name="Basic" contract="RecipeServer.Central.Service.Interfaces.INotificationService" />
        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
          name="mexdata" contract="IMetadataExchange" />
      </service>     
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mexBehavior">
          <serviceMetadata httpGetEnabled="true" />         
        </behavior>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="wsDualHttpBinding" scheme="http" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

客户端实现代码

InstanceContext site = new InstanceContext(new ServiceCallBack());           
try
{             
    client = new NotificationServiceClient(site);
}
catch (Exception e) {
    RecipeLogger.GetInstance.ErrorLog(e.Message);
    RecipeLogger.GetInstance.ErrorLog(e.StackTrace);
}

WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding;
RecipeLogger.GetInstance.DebugLog("2");

binding.ClientBaseAddress = new Uri("http://localhost:8000/myClient/");
string clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri;
RecipeLogger.GetInstance.DebugLog(String.Format("Client baseadd {0}", clientcallbackaddress));
clientcallbackaddress += Guid.NewGuid().ToString();
binding.ClientBaseAddress = new Uri(clientcallbackaddress);
RecipeLogger.GetInstance.DebugLog("Subscribe to central");
client.Subscribe();
client.Close();

问题根因

核心原因是客户端配置中endpoint的contract属性值与客户端代理类实际的契约完全限定名不匹配:

  • 服务端定义的服务契约完全限定名为RecipeServer.Central.Service.Interfaces.INotificationService
  • 客户端App.config中填写的contract为CentralNotificationService.INotificationService,和代理类生成的契约命名空间不一致,WCF客户端构造时无法在配置节中找到匹配的endpoint节点,直接抛出配置错误。
    另外现有代码存在空引用风险:如果NotificationServiceClient构造失败抛出异常,client对象为null,后续直接访问client.Endpoint.Binding会触发二次报错。

修复方案

  • 修正客户端配置的contract值:找到项目中添加服务引用生成的INotificationService接口的完整命名空间,将App.config中endpoint节点的contract属性替换为该完全限定名,保证名称、命名空间完全一致。如果没有配置域环境SPN,建议删除<identity>下的servicePrincipalName配置节点,避免额外身份验证错误。
  • 跳过配置文件读取,手动构造客户端实例(推荐,避免配置不一致问题),修改后的客户端代码如下:
InstanceContext site = new InstanceContext(new ServiceCallBack());
// 手动构造双向绑定,配置回调地址
WSDualHttpBinding binding = new WSDualHttpBinding();
Uri callbackAddress = new Uri($"http://localhost:8000/myClient/{Guid.NewGuid()}");
binding.ClientBaseAddress = callbackAddress;
// 指定服务端地址
EndpointAddress serviceAddress = new EndpointAddress("http://172.18.26.14/CentralService/Services/NotificationService.svc");
// 传入上下文、绑定、地址构造客户端,无需读取App.config配置
var client = new NotificationServiceClient(site, binding, serviceAddress);

try
{
    RecipeLogger.GetInstance.DebugLog("Subscribe to central");
    client.Subscribe();
    client.Close();
}
catch (Exception ex)
{
    RecipeLogger.GetInstance.ErrorLog(ex.Message);
    RecipeLogger.GetInstance.ErrorLog(ex.StackTrace);
    client.Abort();
}
  • 额外排查项:确保本地8000端口未被防火墙拦截、未被其他程序占用,否则wsDualHttpBinding的回调通道无法建立,会出现订阅超时问题。

内容的提问来源于stack exchange,提问作者Le Danh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:42:17