Подтвердить что ты не робот

Почему мой ChannelFactory не видит конфигурацию конечной точки?

Я следил за Miguel Castro за отличную статью о WCF здесь, и все это прекрасно работает, за исключением того, что у меня есть следующий код

public AdminClient()
{
    ChannelFactory<IProductAdmin> factory = new ChannelFactory<IProductAdmin>();
    productAdminChannel = factory.CreateChannel();
}

В моем файле app.config у меня есть следующая конфигурация:

<system.serviceModel>
    <client>
        <endpoint address="net.tcp://localhost:8002/ProductBrowser"
                  binding="netTcpBinding"
                  contract="Contracts.IProductAdmin" />
    </client>
</system.serviceModel>

Но когда я запускаю конструктор для AdminClient, я получаю исключение, говорящее, что конечная точка не определена. Однако, если я изменю свою конфигурацию, чтобы дать конечной точке имя, а затем создать factory следующим образом, он будет работать.

public AdminClient()
{
    var fac = new ChannelFactory<IProductAdmin>("admin");
    productAdminChannel = fac.CreateChannel();
}

<system.serviceModel>
    <client>
        <endpoint name="admin" 
                  address="net.tcp://localhost:8002/ProductBrowser"
                  binding="netTcpBinding"
                  contract="Contracts.IProductAdmin" />
    </client>
</system.serviceModel>

Мне хотелось бы объяснить это. Документация в MSDN не очень помогает...

4b9b3361

Ответ 1

Используйте "*", чтобы использовать первую квалификационную конечную точку.

public AdminClient()
{
    ChannelFactory<IProductAdmin> factory  
         = new ChannelFactory<IProductAdmin>("*");

    productAdminChannel = factory.CreateChannel();
}

Пример MSDN

Ответ 2

Вам нужно указать имя конечной точки, потому что у вас может быть множество конечных точек для одного и того же типа контракта. (Например, служба развертывается на одном tcp и одной конечной точке http ws). Microsoft могла бы, конечно, создать что-то в WCF, чтобы проверить, есть ли только один клиент, указанный для интерфейса контракта, но это было бы не очень последовательным. (что он будет работать, если для контракта есть только одна конечная точка). Когда вы добавите еще одну конечную точку для того же контракта позже, в этом случае код сломается.

Ответ 3

Это прослушивало меня несколько дней, поэтому я просмотрел примеры, приведенные в статье, которую вы указали выше. Все работает правильно, за исключением второго примера прокси-сервера, с которым у вас возникла проблема. Как вы отметили, и другие ответчики, создающие прокси-сервер таким образом, требуют имени конечной точки, связывая его с клиентом (где определяется конечная точка). Я все еще не уверен, почему он ведет себя так, как это делает, но я не нашел способа использовать этот пример без явного связывания прокси-сервера с конечной точкой.

С другой стороны, первый пример, показывающий, как создать прокси-сервер, не требует явного связывания адреса или привязки конечной точки:

 using System;
   using System.ServiceModel;

   namespace CoDeMagazine.ServiceArticle
   {
       public class ProductClient 
          : ClientBase<IProductBrowser>, 
            IProductBrowser
       {

           #region IProductBrowser Members

           public ProductData GetProduct(
              Guid productID)
           {
               return Channel.GetProduct(productID);
           }

           public ProductData[] GetAllProducts()
           {
               return Channel.GetAllProducts();
           }

           public ProductData[] FindProducts(
              string productNameWildcard)
           {
               return Channel.FindProducts(
                  productNameWildcard);
           }

           #endregion
       }

   }

Кажется, все работает отлично. Итак, возможно, второй пример прокси - это просто плохой способ сделать что-то, или, может быть, нам не хватает чего-то очевидного...

Ответ 4

Вы можете уйти, не указав имя конечной точки на стороне службы. Для клиентской стороны вам нужно указать имя, потому что вы можете подключаться к нескольким службам с одним и тем же контрактом. Как бы WCF знал то, что вам нужно?

Ответ 5

Если вы не хотите указывать разницу в имени конечной точки, вы можете написать:

    public AdminClient()
    {
        ChannelFactory<IProductAdmin> factory =  
           new ChannelFactory<IProductAdmin>(string.Empty);
        productAdminChannel = factory.CreateChannel();
    }

Необязательный конструктор без параметров не работает.