以编程方式让客户端应用程序列出在运行时使用 URL 创建的 WCF 服务端点(就像 WCF 测试客户端一样)

Programmatically have Client application list a WCF service's Endpoints created during runtime using a URL (like WCF Test Client does)

也许我没有使用正确的术语进行搜索,因为这看起来很简单。我只是在寻找一种方法来列出 WCF 服务的端点,该服务的端点在 运行 时间以与 WCF 测试客户端相同的方式创建。

  1. 指定URL

  1. 获取元数据和端点

这是我在运行时间

期间添加端点的方式
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();
}

我可以从客户端使用哪些函数来访问与 WCF 测试客户端相同的端点?如果我已经拥有端点的 URL,我知道如何连接到这些端点,但我想要一个端点列表,以便我可以创建一个下拉列表,根据您连接到的主机从更改中进行选择。

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

如果我们有服务元数据 URI,我们可以使用 System.ServiceModel.Description 命名空间中提供的 MetadataExchangeClientMode 和 MetadataResolver class 来检索和处理元数据。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-metadataresolver-to-obtain-binding-metadata-dynamically
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-metadataexchangeclient-to-retrieve-metadata

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

    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 有一个更优雅的解决方案,我现在将对其进行测试。