Проблема с обращением к сервису в WCF - PullRequest
1 голос
/ 13 мая 2011

Я пишу сервис, используя wcf.Я создал решение с двумя проектами:

  • Библиотека: Проект для хранения файлов, относящихся к сервисам (содержащий интерфейс и соответствующие реализации для этого сервиса).Этот проект является библиотечным проектом.
  • Хостинг-приложение Проект для размещения этих сервисов (self-hosting).По этой причине этот проект является исполняемым проектом, имеющим файл конфигурации, в который я помещаю информацию, необходимую для настройки служб.

Я также написал клиента для вызова службы.Это будет называться клиентским приложением .

У меня есть служба.Ниже приведены интерфейс и реализация (проект библиотеки):

namespace EchoWcfLibrary {
    /// <summary>
    /// The interface specifies for those classes implementing it (services), the operation that the service will expose.
    /// </summary>
    [ServiceContract]
    public interface IService1 {
        // This does not use serialization (implicit serialization in considered: base types used).
        [OperationContract]
        string GetData(int value);
        // This uses data contracts and serialization.
        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);
    }

    [DataContract]
    public class CompositeType {
        // Members not serialized
        bool boolValue = true;
        string stringValue = "Hello ";
        // Serialized
        [DataMember]
        public bool BoolValue {
            get { return boolValue; }
            set { boolValue = value; }
        }
        // Serialized
        [DataMember]
        public string StringValue {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
}

Ниже приведен запуск приложения хоста службы (исполняемый проект):

namespace WcfServiceApplication {
    public static class Program {
        static void Main(string[] args) {
            // Setting endpoints and setting the service to start properly.
            // Base address specified: http://localhost:8081/Service1
            Console.WriteLine("Beginning...");
            using (ServiceHost host = new ServiceHost(typeof(Service1), new Uri("http://localhost:8081/Service1"))) {
                Console.WriteLine("Opening host...");
                host.Open();
                Console.WriteLine("Waiting...");
                System.Threading.Thread.Sleep(1000000);
                Console.WriteLine("Closing...");
                host.Close();
                Console.WriteLine("Quitting...");
            }
        }
    }
}

Ниже приводится App.config в исполняемом проекте (хост-приложении):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
    <system.serviceModel>
        <services>
            <service name="WcfServiceLibrary.Service1">
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8081/Service1" />
                    </baseAddresses>
                </host>
                <!-- Service Endpoints -->
                <!-- Unless fully qualified, address is relative to base address supplied above -->
                <endpoint address="/GoInto/Svc" 
                                    binding="basicHttpBinding" 
                                    contract="WcfServiceLibrary.IService1">
                    <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
                    <identity>
                        <dns value="localhost"/>
                    </identity>
                </endpoint>
                <endpoint address="/GoInto/Sav"
                                    binding="basicHttpBinding"
                                    contract="WcfServiceLibrary.IService1">
                    <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
                    <identity>
                        <dns value="localhost"/>
                    </identity>
                </endpoint>
                <!-- Metadata Endpoints -->
                <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
                <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
                <endpoint address="GoInto/Mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            </service>
        </services>

        <behaviors>
            <serviceBehaviors>
                <behavior>
                    <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
                    <serviceMetadata httpGetEnabled="True"/>
                    <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
                    <serviceDebug includeExceptionDetailInFaults="False" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>

</configuration>

Ниже приведен запуск программы в исполняемом проекте клиента (была сделана ссылка на проект библиотеки), в основном это клиент:

namespace WcfServiceClient {
    class Program {
        static void Main(string[] args) {
            ServiceEndpoint httpEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IService1)), new BasicHttpBinding(), new EndpointAddress("http://localhost:8081/Service1"));
            ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>(httpEndpoint);
            IService1 svc = channelFactory.CreateChannel();
            Console.WriteLine(svc.GetData(121));
            System.Threading.Thread.Sleep(10000);
        }
    }
}

Ну ... Моя проблема в следующем: это приложение работает !!!Почему это проблема ???Проблема в том, что я указал при размещении службы в файле App.config три конечные точки: две базовые Http и одну конечную точку метаданных.Ну, я хотел бы обратиться к конечной точке <endpoint address="/GoInto/Svc"..., которая, я предполагаю, что это полный адрес (обратите внимание, что я указал базовый адрес): http://localhost:8081/Service1/GoInto/Svc.

Ну, к сожалению, вклиент, я адресую эту конечную точку: http://localhost:8081/Service1, который является просто базовым адресом ...... ПОЧЕМУ ЭТО РАБОТАЕТ ????Я хочу указать этот адрес в клиенте:

namespace WcfServiceClient {
    class Program {
        static void Main(string[] args) {
            ServiceEndpoint httpEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IService1)), new BasicHttpBinding(), new EndpointAddress("http://localhost:8081/Service1/GoInto/Svc"));
            ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>(httpEndpoint);
            IService1 svc = channelFactory.CreateChannel();
            Console.WriteLine(svc.GetData(121));
            System.Threading.Thread.Sleep(10000);
        }
    }
}

Но если я сделаю это, возникнет ошибка несоответствия:

Сообщение с To 'http://localhost:8081/Service1/GoInto/Svc' не может бытьобработано в получателе из-за несоответствия AddressFilter в EndpointDispatcher.Убедитесь, что конечные адреса отправителя и получателя совпадают.

Почему это не работает?

1 Ответ

1 голос
/ 13 мая 2011

Базовый адрес должен быть указан в одном месте, либо в конструкторе ServiceHost, либо в элементе. Если в обоих местах WCF сгенерирует исключение, сообщающее, что у вас есть два базовых адреса для одной и той же схемы (HTTP).

Скорее всего, это происходит из-за несоответствия имени службы в app.config проекта хостинга, так что конфигурация не выбирается (и вы получаете конечную точку по умолчанию, адрес которой совпадает с один в качестве базового адреса). Попробуйте добавить цикл foreach в код вашего хостинга, и вы должны увидеть адреса конечных точек, которые прослушивает ваш сервис.

                Console.WriteLine("Opening host...");
            host.Open();

            foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
            {
                Console.WriteLine("Endpoint:");
                Console.WriteLine("   Address: {0}", endpoint.Address.Uri);
                Console.WriteLine("   Binding: {0}", endpoint.Binding);
                Console.WriteLine("   Contract: {0}", endpoint.Contract.Name);
            }

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