Программно сделать так, чтобы клиентское приложение перечисляло конечные точки службы WCF, созданные во время выполнения, используя URL-адрес (как это делает тестовый клиент WCF) - PullRequest
2 голосов
/ 19 июня 2019

Возможно, я не ищу правильные термины, потому что это кажется довольно простым. Я просто ищу способ перечислить конечные точки службы WCF, конечные точки которой созданы во время выполнения, так же, как это делает тестовый клиент WCF.

  1. Укажите URL

Add URL

  1. Получение метаданных и конечных точек

enter image description here

Так я добавляю конечные точки во время выполнения

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 Test Client? Я знаю, как подключиться к этим конечным точкам, если у меня уже есть URL-адрес конечной точки, но я хотел бы иметь список конечных точек, чтобы я мог создать выпадающий список на выбор из этих изменений в зависимости от того, к какому хосту вы подключаетесь.

Добавление ссылки на службу через Visual Studio не перечисляет все конечные точки, поскольку они еще не созданы. Это библиотека, которую я могу использовать, чтобы получить их во время выполнения, как это делает WCF Test Client.

Ответы [ 2 ]

2 голосов
/ 20 июня 2019

При условии, что у нас есть URI метаданных службы, мы могли бы использовать класс MetadataExchangeClientMode и MetadataResolver, который предоставляется в пространстве имен System.ServiceModel.Description, для извлечения и обработки метаданных.
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();
}

Результат
enter image description here

0 голосов
/ 20 июня 2019

Хорошо, это было довольно легко сделать, мне просто нужно было использовать MetadataExchangeClient , чтобы получить конфигурацию.В коде все, что мне нужно было сделать, чтобы получить MetaData 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();

Я разместил свой ответ не в том месте.Но у Авраама Цяна есть более элегантное решение, которое я сейчас опробую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...