español wcf rest soap

español - Puntos finales REST/SOAP para un servicio WCF



wcf vs rest (6)

Debemos definir la configuración del comportamiento al punto final REST.

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

y tambien a un servicio

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

Después de los comportamientos, el siguiente paso son los enlaces. Por ejemplo basicHttpBinding a punto final SOAP y webHttpBinding a REST .

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

Finalmente debemos definir el punto final 2 en la definición del servicio. Atención para la dirección = "" del punto final, donde el servicio REST no es necesario nada.

<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>

En la interfaz del servicio definimos la operación con sus atributos.

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); } }

Uniéndose a todas las partes, esta será nuestra definición de 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>

Para probar ambos puntos finales, podemos usar WCFClient para SOAP y PostMan para REST .

Tengo un servicio WCF y quiero exponerlo como un servicio RESTfull y como un servicio SOAP. ¿Alguien ha hecho algo como esto antes?


Esta publicación ya tiene una muy buena respuesta por parte de "Community wiki" y también recomiendo consultar el blog web de Rick Strahl, hay muchas buenas publicaciones sobre WCF Rest como this .

Utilicé ambos para obtener este tipo de servicio MyService ... Entonces puedo usar la interfaz REST de jQuery o SOAP de Java.

Esto es de mi 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>

Y esta es mi clase de servicio (.svc-codebehind, no se requieren interfaces):

/// <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; } }

En realidad, solo uso Json o Xml, pero ambos están aquí para un propósito de demostración. Esas son las solicitudes GET para obtener datos. Para insertar datos yo usaría el método con atributos:

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


Esto es lo que hice para que funcione. Asegúrate de poner
webHttp automaticFormatSelectionEnabled = "true" dentro del comportamiento del punto final.

[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..."; } }

Modelo de servicio interior

<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>

Comportamiento de punto final

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


MSDN parece tener un artículo para esto ahora:

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

Introducción:

De forma predeterminada, Windows Communication Foundation (WCF) hace que los puntos finales estén disponibles solo para los clientes SOAP. En Cómo crear un servicio web HTTP básico de WCF, un punto final está disponible para clientes que no son SOAP. Puede haber ocasiones en las que desee que el mismo contrato esté disponible en ambos sentidos, como punto final web y como punto final SOAP. Este tema muestra un ejemplo de cómo hacer esto.


Puede exponer el servicio en dos puntos finales diferentes. el SOAP puede usar el enlace que soporta SOAP, por ejemplo, basicHttpBinding, el RESTful puede usar el webHttpBinding Supongo que su servicio REST estará en JSON, en ese caso, debe configurar los dos puntos finales con la siguiente configuración de comportamiento

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

Un ejemplo de configuración de punto final en su escenario es

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

Así, el servicio estará disponible en

Aplique [WebGet] al contrato de operación para hacerlo REST. p.ej

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

Tenga en cuenta que si el servicio REST no está en JSON, los parámetros de las operaciones no pueden contener un tipo complejo.

Responder a la publicación de SOAP y RESTful POX (XML)

Para XML antiguo anterior como formato de retorno, este es un ejemplo que funcionaría tanto para SOAP como para XML.

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

Comportamiento POX para REST Plain Old XML

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

Puntos finales

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

El servicio estará disponible en

Solicitud REST intentarlo en el navegador,

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

Configuración de punto final de cliente de solicitud SOAP para el servicio SOAP después de agregar la referencia de servicio,

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

Cía#

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

Otra forma de hacerlo es exponer dos contratos de servicios diferentes y cada uno con una configuración específica. Esto puede generar algunos duplicados a nivel de código, sin embargo, al final del día, desea que funcione.


Si solo desea desarrollar un solo servicio web y alojarlo en muchos puntos finales diferentes (es decir, SOAP + REST, con XML, JSON, CSV, salidas HTML). También debe considerar el uso de ServiceStack que he creado para este propósito exacto donde cada servicio que desarrolla está disponible automáticamente en los puntos finales de SOAP y REST listos para usar sin necesidad de ninguna configuración.

El ejemplo de Hello World muestra cómo crear un servicio simple con solo (no se requiere configuración):

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 }; } }

No se requiere ninguna otra configuración, y este servicio está disponible de inmediato con REST en:

También viene incorporado con una salida HTML amigable (cuando se le llama con un cliente HTTP que tiene Aceptar: texto / html, por ejemplo, un navegador) para que pueda visualizar mejor la salida de sus servicios.

El manejo de diferentes verbos REST también es tan trivial, aquí hay una aplicación CRUD de servicio REST completa en 1 página de C # (menos de lo que se necesitaría para configurar WCF;):