Estoy tratando de construir una interfaz de servicio web genérica utilizando WCF, para permitir que los desarrolladores externos se conecten a nuestro software. Después de mucha lucha y lectura (this question me ayudó mucho), finalmente obtuve SOAP, JSON y XML (POX) trabajando juntos.SOAP/JSON/XML combinados en WCF, usando UriTemplate
Para simplificar, aquí está mi código (para hacer este ejemplo simple, no estoy usando las interfaces - Yo probé esta en ambos sentidos):
<ServiceContract()> _
Public Class TestService
Public Sub New()
End Sub
<OperationContract()> _
<WebGet()> _
Public Function GetDate() As DateTime
Return Now
End Function
'<WebGet(UriTemplate:="getdateoffset/{numDays}")> _
<OperationContract()> _
Public Function GetDateOffset(ByVal numDays As Integer) As DateTime
Return Now.AddDays(numDays)
End Function
End Class
y el código web.config:
<services>
<service name="TestService"
behaviorConfiguration="TestServiceBehavior">
<endpoint address="soap" binding="basicHttpBinding" contract="TestService"/>
<endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="TestService"/>
<endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="TestService"/>
<endpoint address="mex" contract="IMetadataExchange" binding="mexHttpBinding" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
<behavior name="poxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="TestServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
Esto realmente funciona - soy capaz de ir a TestService.svc/xml/GetDate
para XML, JSON para TestService.svc/json/GetDate
, y señalar un cliente SOAP en TestService.svc?wsdl
y tienen el jabón funcionan las consultas.
La parte que me gustaría corregir son las consultas. Tengo que usar TestService.svc/xml/GetDateOffset?numDays=4
en lugar de TestService.svc/xml/GetDateOffset/4
. Si se especifica la UriTemplate, me sale el error:
Endpoints using 'UriTemplate' cannot be used with 'System.ServiceModel.Description.WebScriptEnablingBehavior'.
Pero, por supuesto, sin necesidad de utilizar <enableWebScript/>
, JSON no funciona.
La única otra cosa que he visto que creo que funcionará es hacer 3 servicios diferentes (archivos .svc), que implementen una interfaz que especifique el contrato, pero en las clases especifique diferentes atributos WebGet/WebInvoke en cada clase. Esto parece mucho trabajo extra, francamente, no veo por qué el marco no funciona para mí. La implementación de las clases sería la misma, excepto por los atributos, lo que significa que con el tiempo sería fácil corregir errores/cambios en una implementación, pero no en las otras, lo que generaría un comportamiento incoherente cuando se usa el JSON. Implementación SOAP por ejemplo.
¿Estoy haciendo algo mal aquí? ¿Estoy tomando un enfoque totalmente incorrecto y haciendo mal uso de WCF? ¿Hay una mejor manera de hacer esto?
Con mi experiencia haciendo cosas web, creo que debería ser posible algo de tipo de marco para manejar esto ... Incluso tengo una idea en mi cabeza de cómo construirlo. Parece que se supone que WCF está haciendo esto, y realmente no quiero reinventar la rueda.
¡Tu ejemplo de código aquí fue muy útil! Solo tenía enlaces JSON y descubrí que no podía consumir los servicios de una aplicación .NET, ¡así que esto es lo que buscaba! :) – Shawson
Tenga en cuenta que considero esto completamente obsoleto ahora con [ASP.NET Web API] (http://www.asp.net/web-api); el código que hizo que se formulara esta pregunta hace tiempo que se reescribió utilizando la API web. Recomiendo encarecidamente no usar WCF para nada, a menos que esté [atascado en la edad media y realmente necesite SOAP] (http://stackoverflow.com/questions/11317572/asp-net-webapi-soap). – gregmac