添加UdpAnnouncementEndpoint时ServiceHost抛出NullReferenceException异常
WCF服务公告启动时触发NullReferenceException异常
在实现WCF服务公告功能时,ServiceHost抛出NullReferenceException异常,操作完全按照微软官方文档步骤执行。

环境说明
- 基于.NET Framework 4.8的控制台应用
- 已引用System.ServiceModel和System.ServiceModel.Discovery程序集
- 单独使用UdpDiscovery功能时可正常运行
可复现代码
using System; using System.ServiceModel; using System.ServiceModel.Discovery; [ServiceContract(CallbackContract = typeof(IServerCallback))] public interface IServer { [OperationContract] void Connect(); } [ServiceContract] public interface IServerCallback { [OperationContract] void KeepAlive(); } public class MyServiceHost<TContract, TServer> where TServer : TContract where TContract : IServer { private readonly ServiceHost _serviceHost; private const string MyIp = "10.82.83.84"; public MyServiceHost(TServer server) { var uri = new Uri($"net.tcp://{MyIp}:8586"); _serviceHost = new ServiceHost(server, uri); StartServer(); } private void StartServer() { //Endpoint. var contract = typeof(TContract); _serviceHost.AddServiceEndpoint(contract, new NetTcpBinding(), contract.Name); //服务公告配置 ServiceDiscoveryBehavior serviceDiscoveryBehavior = new ServiceDiscoveryBehavior(); serviceDiscoveryBehavior.AnnouncementEndpoints.Add(new UdpAnnouncementEndpoint()); _serviceHost.Description.Behaviors.Add(serviceDiscoveryBehavior); _serviceHost.Open(); } } [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)] public class Server : IServer { public void Connect(){} } public static class Test { public static void Main(string[] args) { var myServiceHost = new MyServiceHost<IServer, Server>(new Server()); while (Console.ReadLine() != "q"){} } }
问题原因及解决方法
这个异常是因为服务终结点未启用发现功能导致的。虽然添加了ServiceDiscoveryBehavior开启服务级别的发现支持,但每个需要参与公告的终结点必须单独配置EndpointDiscoveryBehavior,否则WCF在发送公告时无法获取有效终结点元数据,进而抛出空引用异常。
修改StartServer方法,在添加终结点后注册EndpointDiscoveryBehavior即可解决:
private void StartServer() { //Endpoint. var contract = typeof(TContract); var endpoint = _serviceHost.AddServiceEndpoint(contract, new NetTcpBinding(), contract.Name); // 为终结点添加发现行为 endpoint.Behaviors.Add(new EndpointDiscoveryBehavior()); //服务公告配置 ServiceDiscoveryBehavior serviceDiscoveryBehavior = new ServiceDiscoveryBehavior(); serviceDiscoveryBehavior.AnnouncementEndpoints.Add(new UdpAnnouncementEndpoint()); _serviceHost.Description.Behaviors.Add(serviceDiscoveryBehavior); _serviceHost.Open(); }
内容的提问来源于stack exchange,提问作者Jossi85
相关产品推荐
相关产品推荐

