Конечные точки REST / SOAP для службы WCF
У меня есть служба WCF, и я хочу представить ее как службу RESTfull и как службу SOAP. Кто-нибудь делал что-то подобное раньше?
6 ответов:
вы можете предоставить службу в двух разных конечных точках. мыло можно использовать для привязки, которая поддерживает SOAP, например, привязка basichttpbinding, спокойный можно использовать привязку 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); }
поведение оспы для отдыха обычный старый XML
<behavior name="poxBehavior"> <webHttp/> </behavior>
конечные точки
<services> <service name="TestService"> <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/> <endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="ITestService"/> </service> </services>
сервис будет доступен в
запрос на отдых попробуйте в браузере,
SOAP request конфигурация конечной точки клиента для службы 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");
другой способ сделать это-предоставить два разных контракта на обслуживание и каждый из них с определенной конфигурацией. Это может создать некоторые дубликаты на уровне кода, однако в конце дня, вы хотите, чтобы он работал.
этот пост уже имеет очень хороший ответ от "Community wiki" , и я также рекомендую посмотреть на веб-блог Рика Штрала, есть много хороших сообщений о WCF Rest, таких как этой.
я использовал оба, чтобы получить этот вид MyService-service... Тогда я могу использовать REST-интерфейс из jQuery или SOAP из Java.
Это из моей сети.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){ //...
Если вы хотите разработать только один веб-сервис и разместить его на разных конечных точках (например, SOAP + REST, с XML, JSON, CSV, HTML outputes). Вы также должны рассмотреть возможность использования ServiceStack который я построил именно для этой цели, где каждая служба, которую вы разрабатываете, автоматически доступна как на SOAP, так и на конечных точках REST out-of-the-box без какой-либо конфигурации.
на Привет, Мир пример показывает, как создайте простой сервис с помощью just (не требуется конфигурация):
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 in:
Он также поставляется в комплекте с дружественный вывод HTML (при вызове с HTTP-клиентом, который имеет принять: текст / html например, браузер), так что вы можете лучше визуализировать выход ваших услуг.
обработка различных глаголов REST также является тривиальной, вот полное приложение REST-service CRUD на 1 странице C# (меньше, чем требуется для настройки WCF ;):
MSDN, кажется, есть статья для этого сейчас:
https://msdn.microsoft.com/en-us/library/bb412196 (v=vs. 110). aspx
интро:
по умолчанию Windows Communication Foundation (WCF) делает конечные точки доступными только для клиентов SOAP. В как создать простую веб-службу WCF через HTTP, конечная точка становится доступной для не-SOAP-клиента. Могут быть случаи, когда вы хотите сделать один и тот же контракт доступным в обоих направлениях, как веб конечная точка и как конечная точка SOAP. В этом разделе приведен пример того, как это сделать.
мы должны определить конфигурацию поведение остальное точка
<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 в мыло конечная точка и webHttpBinding в остальное.
<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> <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 до мыло и почтальон до остальное.
Это то, что я сделал, чтобы заставить его работать. Убедитесь, что вы положили
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>
Поведение Конечной Точки
<endpointBehaviors> <behavior name="jsonBehavior"> <webHttp automaticFormatSelectionEnabled="true" /> <!-- use JSON serialization --> </behavior> </endpointBehaviors>