2013-01-04 3 views
0

У меня есть служба WCF с двумя конечными точками (1 webHttpBinding и 1 basicHttpBinding), которая размещена в IIS. Клиенты могут делать запросы HTTP без проблем. Я смог подключиться и совершать вызовы к конечной точке SOAP через WCFTestClient и смог успешно добавить ссылку на службу в мой проект клиента. Проблема в том, что в файле Reference.cs или файле app.config на клиенте нет кода, сгенерированного на клиенте ... они оба пустые.WCFTestClient подключается, но «Добавить ссылку на службу» не генерирует ссылку

Мой вопрос: почему я могу подключаться и выполнять вызовы в конечную точку SOAP без проблем через WCFTestClient, но не через метод Add Service Reference?

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

Warning 12 Custom tool warning: Cannot import wsdl:portType 
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter 
Error: Referenced type 'MyNamespace.KPI.ChartObject`2, MyNamespace.KPI.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e720b7e8a51f8d5' with data contract name 'ChartObjectOfdecimalZKPIPeriodaU4eboDJ' in namespace 'http://schemas.datacontract.org/2004/07/MyNamespace.KPI' cannot be used since it does not match imported DataContract. Need to exclude this type from referenced types. 

Следует отметить, что этот конкретный классом является общим классом ... Я не знаю, связано ли это с ошибкой.

ответ

1

Вы должны следовать вашей АВС:

  • Адрес
  • Binding
  • контракта

адрес, который экспонируется через HTTP просто нужен URL развертывания. Что интернет-информационная система обрабатывает все это для вас. Однако; если вы попытаетесь использовать Service Reference без соответствующих определений - он не будет отображаться. Поскольку у него есть нет информации о том, куда он направляется.

Как только вы определили эти критерии, он должен появиться на нормальном уровне.


Update:

Вы можете Кульминацией SOAP и REST от того же договора обслуживания или вы можете разделить их. В этом примере; Я их отделим.

Создание службы:

[ServiceContract] 
public interface IMath 
{ 
     [OperationContract] 
     int Add(int Number1, int Number2); 
} 

Создать сервисный контракт для отдыха:

[ServiceContract] 
public interface IMathRest 
{ 

    [OperationContract] 
    [WebGet(UriTemplate = "/Add/{Number1}/{Number2}", RequestFormat = WebMessageFormat.Json, 
       ResponseFormat = WebMessageFormat.Json)] 
    int AddRest(string Number1, string Number2); 
} 

В вышеприведенном службе; он явно устанавливает формат сообщения.

Реализовать службы: "Binding"

public class Math : IMath, IMathRest 
{ 
    public int Add(int Number1, int Number2) 
    { 
     return Number1 + Number2; 
    } 

    public int AddRest(string Number1, string Number2) 
    { 
     int num1 = Convert.ToInt32(Number1); 
     int num2 = Convert.ToInt32(Number2); 
     return num1 + num2; 
    } 
} 

Настройка службы:

<serviceBehaviors> 
     <behavior name = "servicebehavior"> 
      <serviceMetadata httpGetEnabled = "true" /> 
      <serviceDebug includeExceptionDetailInFaults = "false" /> 
     </behavior> 
</serviceBehaviors> 

выше будет установить услугу Basic/Web Http.

После того как вы настроили ваш serviceBehavior вам необходимо определить конечную точку:

<endpointBehaviors> 
    <behavior name="restBehavior"> 
      <webHttp/> 
    </behavior> 
</endpointBehaviors> 

Это настроит Rest Конточку к webHttpBinding указанных выше. Теперь вам нужно определить свое Мыло.

<endpoint name = "SoapEndPoint" 
     contract = "Namespace in which Service Resides goes here" 
     binding = "basicHttpBinding" <!-- Mirrors are above configuration --> 
     address = "soap" /> 

Вышеизложенное войдет в вашу конфигурацию; однако во время потребления услуги - необходимо указать конечное имя. Конечные точки будут доступны на базовом адресе/адресе мыла. Указано используемое связывание.

За исключением того, что мы сконфигурировали наше мыло, а не наш отдых. Таким образом, мы должны определить нашу конечную точку:

<endpoint name = "RestEndPoint" 
     contract = "Namespace that our Rest Interface is located goes here" 
     binding = "webHttpBinding" 
     address = "rest" 
     behaviorCOnfiguration = "restBehavior" /> 

покоиться конечной точки будет называться на нашем URL (Base Address/Отдых/Добавить/Параметр/Parameter). Мы указали наши привязки; и установите наше поведение покоя.

Когда вы положите все это вместе; это будет выглядеть так:

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name ="servicebehavior">   
      <serviceMetadata httpGetEnabled="true"/>   
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="restbehavior"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <services> 
     <service name ="MultipleBindingWCF.Service1" 
       behaviorConfiguration ="servicebehavior" > 
     <endpoint name ="SOAPEndPoint" 
        contract ="MultipleBindingWCF.IService1" 
        binding ="basicHttpBinding" 
        address ="soap" /> 

     <endpoint name ="RESTEndPoint" 
        contract ="MultipleBindingWCF.IService2" 
        binding ="webHttpBinding" 
        address ="rest" 
        behaviorConfiguration ="restbehavior"/> 

     <endpoint contract="IMetadataExchange" 
        binding="mexHttpBinding" 
        address="mex" /> 
     </service> 
    </services> 
    </system.serviceModel> 
<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 
</configuration> 

Потребляя:

Употреблять наше мыло просто; прямо. Сделайте ссылку на службу и выполните вызов.

static void CallingSoapFunction() 
{ 
    SoapClient proxy = new SoapClient("SoapEndPoint"); 
    var result = proxy.Add(7,2); // Proxy opens the channel, we invoke our method, we input our parameters. 
    Console.WriteLine(result); 
} 

За исключением нашего спокойного потребления немного отличается; тем более, что мы должны отформатировать его до Json. Поэтому нам нужно точно указать имя.

Отдых будет полагаться на Json для де-сериализации данных.

static void CallRestFunc() 
{ 
    WebClient RestProxy = new WebClient(); 
    byte[] data = RestProxy.DownloadData(new Uri("http://localhost:30576/MathRest.svc/Rest/Add/7/2")); // As you see it is following the exact location of the project, invoking method/parameter and so on down the line. 
Stream stream = new MemoryStream(data); 
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(string)); 
string result = obj.ReadObject(stream).ToString(); 
Console.WriteLine(result); 
} 

Вышеупомянутые данные будут загружены с использованием Rest Uri. Десериализовать эти данные; и становятся отображаемыми.

Надеюсь, это поможет уточнить.

Если соответствующие элементы не были созданы в вашем файле конфигурации; то это не позволит надлежащего потребления. ABC имеют решающее значение в WCF. Если он не создан в файле конфигурации, вам необходимо будет программно создать их в коде.


Update:

static void Main(string[] args) 
{ 
    var binding = new BasicHttpBinding(); 
    var endpoint = new EndpointAddress("http://localhost:8080/"); 
    using (var factory = new ChannelFactory<IPerson>(binding, endpoint)) 
    { 
     var request = new Dictionary<Guid, Person>(); 
     request[Guid.NewGuid()] = new Person { Name = "Bob", Email = "[email protected]" }; 

     var client = factory.CreateChannel(); 
     var result = client.SetCustomer(request); 

     Console.WriteLine("Name: {0} | Email: {1}", result.Name, result.Email); 
     factory.Close(); 
    } 
    Console.ReadKey(true); 
} 

Как вы видите, в этом простом примере; привязка и конечная точка настроены. Вы должны убедиться, что все они определены как на вашем сервере, так и на клиенте. Он должен знать, куда он идет. Это имеет смысл?

+0

Я не уверен, что следую ... Я использовал [это] (http://stackoverflow.com/questions/186631/rest-soap-endpoints-for-a-wcf-service) в качестве руководства для реализации мой сервис. Что позволит мне использовать WCFTestClient, но * не * ссылку на службу в моем собственном приложении? – Thelonias

+0

Он, надеюсь, прояснит; особенно при абстракции. http://www.codeproject.com/Articles/406096/A-beginners-tutorial-for-understanding-Windows – Greg

+0

Эта статья по-прежнему следует за ABC. – Greg

Смежные вопросы