Конечные точки REST/SOAP для службы WCF

У меня есть служба WCF, и я хочу показать ее как службу RESTfull, так и службу SOAP. Кто-нибудь сделал что-то подобное раньше?

Ответы

Ответ 1

Вы можете открыть службу в двух разных конечных точках. SOAP можно использовать привязку, которая поддерживает SOAP, например. basicHttpBinding, RESTful можно использовать webHttpBinding. Я предполагаю, что ваша служба REST будет находиться в JSON, в этом случае вам необходимо настроить две конечные точки со следующей конфигурацией поведения

<endpointBehaviors>
  <behavior name="jsonBehavior">
    <enableWebScript/>
  </behavior>
</endpointBehaviors>

Примером конфигурации конечной точки в вашем сценарии является

<services>
  <service name="TestService">
    <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
    <endpoint address="json" binding="webHttpBinding"  behaviorConfiguration="jsonBehavior" contract="ITestService"/>
  </service>
</services>

поэтому услуга будет доступна в

Применить [WebGet] к контракту операции, чтобы сделать его RESTful. например.

public interface ITestService
{
   [OperationContract]
   [WebGet]
   string HelloWorld(string text)
}

Обратите внимание: если служба REST не находится в JSON, параметры операций не могут содержать сложный тип.

Ответить на сообщение для SOAP и RESTful POX (XML)

Для простого старого XML в качестве формата возврата это пример, который будет работать как для SOAP, так и для XML.

[ServiceContract(Namespace = "http://test")]
public interface ITestService
{
    [OperationContract]
    [WebGet(UriTemplate = "accounts/{id}")]
    Account[] GetAccount(string id);
}

Поведение POX для REST Обычный старый XML

<behavior name="poxBehavior">
  <webHttp/>
</behavior>

Endpoints

<services>
  <service name="TestService">
    <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
    <endpoint address="xml" binding="webHttpBinding"  behaviorConfiguration="poxBehavior" contract="ITestService"/>
  </service>
</services>

Сервис будет доступен в

Запрос REST попробуйте в браузере,

http://www.example.com/xml/accounts/A123

Запрос SOAP конфигурации конечной точки клиента для службы SOAP после добавления служебной ссылки,

  <client>
    <endpoint address="http://www.example.com/soap" binding="basicHttpBinding"
      contract="ITestService" name="BasicHttpBinding_ITestService" />
  </client>

в С#

TestServiceClient client = new TestServiceClient();
client.GetAccount("A123");

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

Ответ 2

У этого сообщения уже есть очень хороший ответ от "Community wiki", и я также рекомендую посмотреть блог Rick Strahl Web, есть много хороших сообщений о WCF Rest, например это.

Я использовал оба метода для получения такого сервиса MyService... Затем я могу использовать REST-интерфейс из jQuery или SOAP с Java.

Это из моего Web.Config:

<system.serviceModel>
 <services>
  <service name="MyService" behaviorConfiguration="MyServiceBehavior">
   <endpoint name="rest" address="" binding="webHttpBinding" contract="MyService" behaviorConfiguration="restBehavior"/>
   <endpoint name="mex" address="mex" binding="mexHttpBinding" contract="MyService"/>
   <endpoint name="soap" address="soap" binding="basicHttpBinding" contract="MyService"/>
  </service>
 </services>
 <behaviors>
  <serviceBehaviors>
   <behavior name="MyServiceBehavior">
    <serviceMetadata httpGetEnabled="true"/>
    <serviceDebug includeExceptionDetailInFaults="true" />
   </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
   <behavior name="restBehavior">
    <webHttp/>
   </behavior>
  </endpointBehaviors>
 </behaviors>
</system.serviceModel>

И это мой служебный класс (.svc-codebehind, без интерфейса):

    /// <summary> MyService documentation here ;) </summary>
[ServiceContract(Name = "MyService", Namespace = "http://myservice/", SessionMode = SessionMode.NotAllowed)]
//[ServiceKnownType(typeof (IList<MyDataContractTypes>))]
[ServiceBehavior(Name = "MyService", Namespace = "http://myservice/")]
public class MyService
{
    [OperationContract(Name = "MyResource1")]
    [WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate = "MyXmlResource/{key}")]
    public string MyResource1(string key)
    {
        return "Test: " + key;
    }

    [OperationContract(Name = "MyResource2")]
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "MyJsonResource/{key}")]
    public string MyResource2(string key)
    {
        return "Test: " + key;
    }
}

На самом деле я использую только Json или Xml, но оба они предназначены для демонстрационной цели. Это GET-запросы для получения данных. Для вставки данных я бы использовал метод с атрибутами:

[OperationContract(Name = "MyResourceSave")]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "MyJsonResource")]
public string MyResourceSave(string thing){
    //...

Ответ 3

Если вы хотите создать только один веб-сервис и разместить его на разных концах (например, SOAP + REST, с XML-данными, JSON, CSV, HTML-выводами). Вы также должны рассмотреть возможность использования ServiceStack, который я построил именно для этой цели, когда каждая работающая вами служба автоматически доступный как на конечных точках SOAP, так и на REST без необходимости настройки.

Пример Hello World показывает, как создать простой сервис с помощью просто (без необходимости настройки):

public class Hello {
    public string Name { get; set; }
}

public class HelloResponse {
    public string Result { get; set; }
}

public class HelloService : IService
{
    public object Any(Hello request)
    {
        return new HelloResponse { Result = "Hello, " + request.Name };
    }
}

Никакой другой конфигурации не требуется, и эта служба немедленно доступна с помощью REST в:

Он также встроен с дружественным HTML-выходом (при вызове с HTTP-клиентом, который имеет Accept: text/html, например, браузер), чтобы вы могли лучше визуализировать выходные данные своих сервисов.

Обработка разных глаголов REST также является тривиальной, здесь полное приложение CRUD-сервиса REST на 1 странице С# (меньше, чем это требуется для настройки WCF;):

Ответ 4

У MSDN есть статья для этого сейчас:

https://msdn.microsoft.com/en-us/library/bb412196(v=vs.110).aspx

Вступление:

По умолчанию Windows Communication Foundation (WCF) делает конечные точки доступными только для клиентов SOAP. В разделе Как создать базовую веб-HTTP-службу WCF конечная точка доступна для клиентов, не относящихся к SOAP. Могут быть случаи, когда вы хотите сделать один и тот же контракт доступным в обоих направлениях, в качестве конечной точки Web и в качестве конечной точки SOAP. В этом разделе показан пример того, как это сделать.