wcf - разница - soap vs rest




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

Вы можете открыть службу в двух разных конечных точках. 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 Plain Old 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>

в C #

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

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

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


Если вы хотите создать только один веб-сервис и разместить его на разных конечных точках (например, 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 странице C # (меньше, чем требуется для настройки WCF;):


Мы должны определить конфигурацию поведения для конечной точки REST

<endpointBehaviors>
  <behavior name="restfulBehavior">
   <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
  </behavior>
</endpointBehaviors>

а также к услуге

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

После поведения следующий шаг - привязки. Например, basicHttpBinding для конечной точки SOAP и webHttpBinding для REST .

<bindings>
   <basicHttpBinding>
     <binding name="soapService" />
   </basicHttpBinding>
   <webHttpBinding>
     <binding name="jsonp" crossDomainScriptAccessEnabled="true" />
   </webHttpBinding>
</bindings>

Наконец, мы должны определить 2 конечную точку в определении службы. Внимание к адресу = "" конечной точки, где услуга REST ничего не нужно.

<services>
  <service name="ComposerWcf.ComposerService">
    <endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding" bindingConfiguration="jsonp" name="jsonService" contract="ComposerWcf.Interface.IComposerService" />
    <endpoint address="soap" binding="basicHttpBinding" name="soapService" contract="ComposerWcf.Interface.IComposerService" />
    <endpoint address="mex" binding="mexHttpBinding" name="metadata" contract="IMetadataExchange" />
  </service>
</services>

В интерфейсе службы мы определяем операцию с ее атрибутами.

namespace ComposerWcf.Interface
{
    [ServiceContract]
    public interface IComposerService
    {
        [OperationContract]
        [WebInvoke(Method = "GET", UriTemplate = "/autenticationInfo/{app_id}/{access_token}", ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
        Task<UserCacheComplexType_RootObject> autenticationInfo(string app_id, string access_token);
    }
}

Присоединившись ко всем сторонам, это будет наше определение WCF system.serviceModel.

<system.serviceModel>

  <behaviors>
    <endpointBehaviors>
      <behavior name="restfulBehavior">
        <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior>
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
  </behaviors>

  <bindings>
    <basicHttpBinding>
      <binding name="soapService" />
    </basicHttpBinding>
    <webHttpBinding>
      <binding name="jsonp" crossDomainScriptAccessEnabled="true" />
    </webHttpBinding>
  </bindings>

  <protocolMapping>
    <add binding="basicHttpsBinding" scheme="https" />
  </protocolMapping>

  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

  <services>
    <service name="ComposerWcf.ComposerService">
      <endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding" bindingConfiguration="jsonp" name="jsonService" contract="ComposerWcf.Interface.IComposerService" />
      <endpoint address="soap" binding="basicHttpBinding" name="soapService" contract="ComposerWcf.Interface.IComposerService" />
      <endpoint address="mex" binding="mexHttpBinding" name="metadata" contract="IMetadataExchange" />
    </service>
  </services>

</system.serviceModel>

Для тестирования обеих конечных точек мы можем использовать WCFClient для SOAP и PostMan для REST .


Это то, что я сделал, чтобы заставить его работать. Убедитесь, что вы положили
webHttp automaticFormatSelectionEnabled = "true" внутри поведения конечной точки.

[ServiceContract]
public interface ITestService
{

    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/product", ResponseFormat = WebMessageFormat.Json)]
    string GetData();
}

public class TestService : ITestService
{
    public string GetJsonData()
    {
        return "I am good...";
    }
}

Внутренняя модель обслуживания

   <service name="TechCity.Business.TestService">

    <endpoint address="soap" binding="basicHttpBinding" name="SoapTest"
      bindingName="BasicSoap" contract="TechCity.Interfaces.ITestService" />
    <endpoint address="mex"
              contract="IMetadataExchange" binding="mexHttpBinding"/>
    <endpoint behaviorConfiguration="jsonBehavior" binding="webHttpBinding"
              name="Http" contract="TechCity.Interfaces.ITestService" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8739/test" />
      </baseAddresses>
    </host>
  </service>

Поведение EndPoint

  <endpointBehaviors>
    <behavior name="jsonBehavior">
      <webHttp automaticFormatSelectionEnabled="true"  />
      <!-- use JSON serialization -->
    </behavior>
  </endpointBehaviors>




soap