C# 以编程方式将客户端应用程序列表设置为WCF服务';s在运行时使用URL创建的端点(与WCF测试客户端类似)

C# 以编程方式将客户端应用程序列表设置为WCF服务';s在运行时使用URL创建的端点(与WCF测试客户端类似),c#,wcf,C#,Wcf,也许我没有用正确的术语搜索,因为这看起来很简单。我只是在寻找一种方法来列出一个WCF服务的端点,该服务在运行时创建了它的端点,就像WCF测试客户端那样 指定URL 获取元数据和端点 这是我在运行时添加端点的方式 string SetInstrumentsURL = serviceUrl + "SetInstruments/"; string SetInstrumentsPipe = "net.pipe://localhost/TestService/SetInstruments/"; Ser

也许我没有用正确的术语搜索,因为这看起来很简单。我只是在寻找一种方法来列出一个WCF服务的端点,该服务在运行时创建了它的端点,就像WCF测试客户端那样

  • 指定URL
  • 获取元数据和端点
  • 这是我在运行时添加端点的方式

    string SetInstrumentsURL = serviceUrl + "SetInstruments/";
    string SetInstrumentsPipe = "net.pipe://localhost/TestService/SetInstruments/";
    ServiceHost SetInstrumentsHost = null;
    var SetInstruments = InstrumentLoader.Factory.GetIEnumerableOf<ISetInstrument>();
    if (SetInstruments.Count() > 0)
    {
        Uri SetInstrumentsURI = new Uri(SetInstrumentsURL);
        Uri SetInstrumentsPipedURI = new Uri(SetInstrumentsPipe);
        NetTcpBinding netTcpBindingSetInstruments = new NetTcpBinding();
        NetNamedPipeBinding NamedPipeBindingSetInstruments = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
        SetInstrumentsHost = new ServiceHost(typeof(TeraSetInstrumentService), new Uri[] { SetInstrumentsURI, SetInstrumentsPipedURI });
        ServiceMetadataBehavior SetInstrumentServiceMetadataBehavior = new ServiceMetadataBehavior();
        SetInstrumentsHost.Description.Behaviors.Add(SetInstrumentServiceMetadataBehavior);
        SetInstrumentsHost.AddServiceEndpoint(typeof(IMetadataExchange),
        MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
        SetInstrumentsHost.AddServiceEndpoint(typeof(IMetadataExchange),
        MetadataExchangeBindings.CreateMexNamedPipeBinding(), "mex");
        foreach (var setter in SetInstruments)
        {
            SetInstrumentsHost.AddServiceEndpoint(typeof(ISetInstrumentService), netTcpBindingSetInstruments, SetInstrumentsURL + setter.Name).Name = "Set_" + setter.Name.Replace(" ", "_");
            SetInstrumentsHost.AddServiceEndpoint(typeof(ISetInstrumentService), NamedPipeBindingSetInstruments, SetInstrumentsPipe + setter.Name).Name = "Set_" + setter.Name.Replace(" ", "_");
        }
        SetInstrumentsHost.Open();
    }
    
    字符串SetInstrumentsURL=serviceUrl+“SetInstruments/”;
    字符串SetInstrumentsPipe=“net。pipe://localhost/TestService/SetInstruments/";
    ServiceHost SetInstrumentsHost=null;
    var SetInstruments=InstrumentLoader.Factory.GetIEnumerableOf();
    如果(SetInstruments.Count()>0)
    {
    Uri SetInstrumentsURI=新Uri(SetInstrumentsURL);
    Uri setInstrumentSpipeUri=新Uri(SetInstrumentsPipe);
    NetTcpBinding netTcpBindingSetInstruments=新的NetTcpBinding();
    NetNamedPipeBinding NamedPipeBindingSetInstruments=新的NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
    SetInstrumentsHost=新服务主机(typeof(TeraSetInstrumentService),新Uri[]{SetInstrumentsURI,SetInstrumentsPipedURI});
    ServiceMetadataBehavior SetInstrumentServiceMetadataBehavior=新ServiceMetadataBehavior();
    SetInstrumentsHost.Description.Behaviors.Add(SetInstrumentServiceMetadataBehavior);
    SetInstrumentsHost.AddServiceEndpoint(类型为(IMetadataExchange),
    MetadataExchangeBindings.CreateMexTcpBinding(),“mex”);
    SetInstrumentsHost.AddServiceEndpoint(类型为(IMetadataExchange),
    MetadataExchangeBindings.CreateMexNamedPipeBinding(),“mex”);
    foreach(SetInstruments中的var设置器)
    {
    SetInstrumentsHost.AddServiceEndpoint(typeof(ISetInstrumentService),nettcBindingSetInstruments,SetInstrumentsURL+setter.Name).Name=“Set_”+setter.Name.Replace(“,”);
    SetInstrumentsHost.AddServiceEndpoint(typeof(ISetInstrumentService),NamedPipeBindingSetInstruments,SetInstrumentsPipe+setter.Name)。Name=“Set_”+setter.Name.Replace(“,”);
    }
    SetInstrumentsHost.Open();
    }
    
    我可以从客户端使用哪些函数来访问与WCF测试客户端相同的端点?如果我已经有了端点的URL,我知道如何连接到这些端点,但我希望有一个端点列表,这样我就可以创建一个下拉列表,根据您连接到的主机的不同从中进行选择


    通过Visual Studio添加服务引用不会列出所有端点,因为尚未创建。是一个库,我可以像WCF测试客户端一样在运行时获取它们。

    如果我们有服务元数据URI,我们可以使用System.ServiceModel.Description命名空间中提供的MetadataExchangeClientMode和MetadataResolver类来检索和处理元数据。


    我举了一个简单的例子,希望对你有用。

        class Program
        {
            static void Main(string[] args)
            {
                Uri uri = new Uri("http://10.157.13.69:3336/mex");
                MetadataExchangeClient client = new MetadataExchangeClient(uri, MetadataExchangeClientMode.MetadataExchange);
                MetadataSet metadata = client.GetMetadata();
                WsdlImporter importer = new WsdlImporter(metadata);
                ServiceEndpointCollection endpoints = importer.ImportAllEndpoints();
    
                //ServiceEndpointCollection endpoints = MetadataResolver.Resolve(typeof(IService), uri, MetadataExchangeClientMode.MetadataExchange);
                foreach (var item in endpoints)
                {
                    Console.WriteLine(item.Address.Uri);
                }
            }
        }
        [ServiceContract]
        public interface IService
        {
            [OperationContract]
            string SayHello();
    }
    
    结果


    好的,这很容易做到,我只需要使用MetadataExchangeClient来获取配置。在代码中,获取元数据Xml所需的全部操作如下:

    var meta = new System.ServiceModel.Description.MetadataExchangeClient(new Uri("net.tcp://10.0.2.124:9000/TeraService/SetInstruments/mex"), System.ServiceModel.Description.MetadataExchangeClientMode.MetadataExchange);
    var data = meta.GetMetadata();
    System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(data.GetType());
    TextWriter writer = new StreamWriter("xmlfile.xml");
    x.Serialize(writer, data);
    writer.Close();
    

    我把答案贴错了地方。但是Abraham Qian有一个更优雅的解决方案,我现在将对其进行测试。

    据我所知,我们可以使用ChannelFactory通过指定端点地址手动创建通信通道,然后调用服务。我们可以使用SVCUTIL.exe工具获得这些端点。我忘了补充一点,我正试图以编程方式获取这些端点,所以如果有一个C#库可以使用,那将是最好的。我觉得服务模型库应该有这样的功能。