Почему мой ChannelFactory не видит мою конфигурацию конечной точки? - PullRequest
46 голосов
/ 09 января 2009

Я следил за прекрасной статьей Мигеля Кастро о 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, я получаю исключение, говорящее, что конечная точка не определена. Однако, если я изменю свою конфигурацию, чтобы дать конечной точке имя, а затем создаю фабрику следующим образом, это работает.

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 не сильно помогает ...

Ответы [ 5 ]

61 голосов
/ 12 февраля 2010

Используйте «*» для использования первой подходящей конечной точки.

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

    productAdminChannel = factory.CreateChannel();
}

Пример MSDN

3 голосов
/ 09 января 2009

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

2 голосов
/ 14 января 2009

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

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

 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
       }

   }

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

1 голос
/ 22 октября 2009

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

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

Конструктор без параметров, ненужный, не работает.

1 голос
/ 09 января 2009

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

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