创建支持公网访问的自托管WCF服务遇EndpointNotFoundException求助
排查WCF公网访问的EndpointNotFoundException问题
让我帮你一步步梳理问题,你已经做了端口转发、防火墙配置这些基础工作,但还有几个容易忽略的细节需要修正:
1. 先修正客户端地址的低级错误
你的公网客户端代码里的地址有两个致命问题:
// 错误的地址:开头有空格 + 域名后多了个冒号 EndpointAddress uri = new EndpointAddress(" http://fabianwesling.dynu.com/:28620/HostManager/Service");
修正后的正确地址应该是:
EndpointAddress uri = new EndpointAddress("http://fabianwesling.dynu.com:28620/HostManager/Service");
- 去掉地址开头的空格,空格会导致WCF无法解析正确的端点地址
- 把
dynu.com/:28620改成dynu.com:28620,冒号应该紧跟域名,而不是在斜杠后面
2. 服务主机的绑定方式错误(核心问题)
你在公网服务器的代码里直接用公网域名创建ServiceHost,这是不对的:
// 错误:服务器本身没有公网IP,无法绑定到公网域名的Uri Uri http_Uri = new Uri("http://fabianwesling.dynu.com:28620/HostManager/Service"); host = new ServiceHost(typeof(HostManager.Services.Service), http_Uri);
正确的做法:
服务器应该绑定到内网IP或者0.0.0.0(监听所有网卡),因为公网IP是路由器的,你的服务器处于内网,只能绑定自己的内网IP:
// 绑定到你的内网IP(和本地运行时的IP一致) Uri http_Uri = new Uri("http://192.168.1.100:28620/HostManager/Service"); // 或者绑定到0.0.0.0,监听服务器所有网卡的28620端口 // Uri http_Uri = new Uri("http://0.0.0.0:28620/HostManager/Service"); host = new ServiceHost(typeof(HostManager.Services.Service), http_Uri); // 建议显式添加端点,避免Configure方法的自动绑定出现问题 host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), ""); // 保留你的行为配置 var metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); if (metadataBehavior == null) { metadataBehavior = new ServiceMetadataBehavior { HttpGetEnabled = true }; host.Description.Behaviors.Add(metadataBehavior); } var debugBehavior = host.Description.Behaviors.Find<ServiceDebugBehavior>(); if (debugBehavior == null) { debugBehavior = new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true }; host.Description.Behaviors.Add(debugBehavior); } host.Open();
这样服务会在内网的28620端口监听,再通过路由器的端口转发把公网的28620端口映射到服务器的192.168.1.100:28620。
3. 验证端口转发和服务可用性
做完上面的修改后,按以下步骤验证:
- 本地验证:在服务器上访问
http://192.168.1.100:28620/HostManager/Service?wsdl,如果能正常显示WSDL文档,说明本地服务运行正常。 - 公网验证:在其他网络(比如手机流量)访问
http://fabianwesling.dynu.com:28620/HostManager/Service?wsdl,如果能获取到WSDL,说明端口转发生效;如果不能,再检查路由器的端口转发规则:- 确认转发的是TCP协议(BasicHttpBinding基于TCP)
- 外部端口和内部端口都是28620,目标IP是你的服务器内网IP
192.168.1.100 - 可以用PowerShell命令测试端口连通性:
Test-NetConnection fabianwesling.dynu.com -Port 28620,如果显示TcpTestSucceeded: True,说明端口是通的。
4. 关于NetTcpBinding的额外说明
如果后续要启用NetTcpBinding的公网访问,需要注意:
- NetTcp默认用的是TCP端口,同样需要在路由器上转发28621端口到服务器的
192.168.1.100:28621 - 公网客户端访问NetTcp端点时,地址应该是
net.tcp://fabianwesling.dynu.com:28621/HostManager/Service,同样要注意地址的语法错误
内容的提问来源于stack exchange,提问作者Fabian Wesling
相关产品推荐
相关产品推荐

