.net - restful - wcf tutorial
CombinaciĆ³n de SOAP/JSON/XML en WCF, utilizando UriTemplate (3)
Estoy intentando 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 ( esta pregunta me ayudó mucho), finalmente obtuve SOAP, JSON y XML (POX) trabajando juntos.
Para simplificar, aquí está mi código (para simplificar este ejemplo, no estoy usando interfaces, lo intenté de ambas formas):
<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: puedo ir a TestService.svc/xml/GetDate
para xml, TestService.svc/json/GetDate
para json, y apuntar a un cliente SOAP en TestService.svc?wsdl
y hacer que las consultas SOAP funcionen.
La parte que me gustaría corregir son las consultas. Tengo que usar TestService.svc/xml/GetDateOffset?numDays=4
lugar de TestService.svc/xml/GetDateOffset/4
. Si especifico el UriTemplate, obtengo el error:
Endpoints using ''UriTemplate'' cannot be used with ''System.ServiceModel.Description.WebScriptEnablingBehavior''.
Pero, por supuesto, sin utilizar <enableWebScript/>
, JSON no funciona.
La única otra cosa que he visto que creo que funcionará es crear 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 en la red, creo que debería ser posible que algún tipo de marco maneje esto ... Incluso tengo una idea en mi cabeza sobre cómo construirlo. Parece que se supone que WCF está haciendo esto, y realmente no quiero reinventar la rueda.
En realidad, <enableWebScript />
no es necesario para el soporte "puro" de JSON. El WebScriptEnablingBehavior
solo es necesario si desea admitir ASP.NET AJAX. En la mayoría de los casos, si intenta trabajar con librerías de scripts estándar, no desea habilitar este soporte para sus servicios.
En cambio, lo que desea hacer para su punto final JSON es simplemente usar WebHttpBehavior
y establecer DefaultOutgoingResponseFormat = "JSON". El problema es que, en .NET 3.5, no puede controlar esta configuración a través de config porque WebHttpElement
no expone estas propiedades para la configuración. Para solucionar esto, en 3.5 hemos proporcionado una implementación para lo que llamo EnhancedWebHttpElement
aquí en esta respuesta a otra pregunta de .
Afortunadamente, Microsoft se dio cuenta de esta falla y habilitó la configuración de todos los ajustes de WebHttpElement
través de WebHttpElement
en 4.0 .
Has especificado parámetros enteros en tu operación. La plantilla de URI no funciona bien con los parámetros int. Por favor, cámbialo a una cadena, Funcionará.
Creo que tienes que escribir tu propio QuerystringConverter para usar int con URITemplate.
La respuesta de Drew es acertada, pero creo que la pregunta sigue en pie. ¿Hay una manera sensata de tener JSON para AJAX () y las bendiciones de UriTemplate?
Creo que vale la pena mencionar que JSON devuelto es diferente de JSON generado con [WebGet (ResponseFormat = WebMessageFormat.Json)]. El primero se ajusta al elemento ''d'' de MS AJAX, por ejemplo {"d": [{...}]}.