2009-09-29 41 views
10

Estoy luchando algunas horas con esto y no puedo encontrar una solución al problema de comunicación. Mi servicio necesita comunicarse con los clientes a través de SOAP o XML simpleServicio WCF, respuesta en SOAP o XML simple, ¿cómo?

Mi servicio se escribirá en base al marco WCF, pero mis clientes no.

¿Podría mostrarme paso a paso cómo cambiar el código y la configuración de mi servicio de manera que devuelva el mensaje SOAP o XML? Estoy interesado en ambas soluciones.

He tratado de conseguir esto basándose en esta respuesta:

REST/SOAP endpoints for a WCF service Call WCF Using SOAP call

Pero nada de esta solución ha funcionado correctamente para mí. O no recibí nada en mi navegador o error que no se pudo encontrar el recurso.

Así que comencé un nuevo Proyecto de Servicio WCF. Se ejecuta bajo http://localhost:3151/ y tienen un código como éste:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 

namespace WcfService1 
{ 
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file. 
    public class Service1 : IService1 
    { 
     public string GetData(int value) 
     { 
      return string.Format("You entered: {0}", value); 
     } 

     public CompositeType GetDataUsingDataContract(CompositeType composite) 
     { 
      if (composite.BoolValue) 
      { 
       composite.StringValue += "Suffix"; 
      } 
      return composite; 
     } 
    } 
} 

Probablemente I'will necesitan para crear dos puntos finales? Ambos deberían contener basicHttpBinding como parámetro de enlace. ¿Pero qué más?

También, cómo producir un XML como esto (sobre la base de un contrato de datos):

<CompositeType BoolValue = 0 StringValue = ""> 

en lugar de esto:

<CompositeType> 
    <BoolValue>0</BoolValue> 
    <StringValue></StringValue> 
</CompositeType> 

Tenga en cuenta que necesito como una comunicación bidireccional, de manera mi servicio necesita recibir SOAP o XML y respuesta en SOAP o XML.

Además, si esto es posible, me gustaría ver la descripción de los métodos de servicio en mi navegador al igual que en ASP .NET.

Gracias de antemano por su tiempo.

Muy gran actualización aquí abajo

he tratado de encontrar alguna solución y aquí es todo lo que he reunido hasta el momento. Me he centrado solo en XML simple.

permite decir que el protocolo es el siguiente:

mensaje de un cliente:

<MESSAGE MessageParam1 = 0> 
    <AdditionalInfo>Some message info </AdditionalInfo> 
</MESSAGE> 

Respuesta:

<RESPONSE ResponseParam1 = 0> 
    <AdditionalInfo>Some response info</AdditionalInfo> 
</MESSAGE> 

En primer lugar, me gustaría ver la descripción del actual métodos de servicio y parámetros en el formato exacto que se enviarán/recibirán. Lo que quiero decir es que cuando se experimentó con ASP .NET 2.0 Servicios Web cuando invoca servicio en mi navegador (acaba de comenzar el servicio) Tengo dicha respuesta:

POST /Service1.asmx HTTP/1.1 
Host: localhost 
Content-Type: text/xml; charset=utf-8 
Content-Length: length 
SOAPAction: "http://tempuri.org/ShowUser" 

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
    <ShowUser xmlns="http://tempuri.org/"> 
     <MyLogin> 
     <User>string</User> 
     <Password>string</Password> 
     <Database>string</Database> 
     </MyLogin> 
    </ShowUser> 
    </soap:Body> 
</soap:Envelope> 

HTTP/1.1 200 OK 
Content-Type: text/xml; charset=utf-8 
Content-Length: length 

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
    <ShowUserResponse xmlns="http://tempuri.org/"> 
     <ShowUserResult>string</ShowUserResult> 
    </ShowUserResponse> 
    </soap:Body> 
</soap:Envelope> 

y esto es excelente.Aparte de eso, esto tiene un sobre SOAP (los datos subyacentes también son diferentes), pero el punto es que puedo mostrarlo al cliente y decirle: "estás haciendo un método HTTP POST con dicha estructura XML y estás recibiendo esa respuesta". Quiero un resultado similar con WCF pero aún más simple, sin SOAP. Hasta ahora, cuando hago clic en Service1.svc obtengo un montón de código WSDL que no quiero. Sé que esto es genial para algunos casos, pero no sé qué plataforma está usando mi cliente. Y si no va a usar .NET, probablemente no importe correctamente el WSDL.

Así que ya sabes lo que me gustaría obtener.

Esto es lo que he hecho hasta ahora después de dos días largos ...:

namespace RESTService 
{ 
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config. 

    [ServiceContract] 
    [XmlSerializerFormat] 
    public interface IService 
    { 
     [OperationContract] 
     [WebGet] 
     Response EchoWithGet(string s); 

     [OperationContract] 
     [WebInvoke] 
     Response EchoWithPost(string s); 
    } 

    public class Response 
    { 
     [XmlAttribute] 
     public int ResponseParam1; 
     [XmlElement] 
     public string AdditionalInfo; 
    } 
} 

Como se puede ver que no proporcionó la clase de mensajes, porque no sé cómo pasar al método a través del navegador . Solo sé cómo pasar una cuerda.

Y aquí es la implementación y configuración:

namespace RESTService 
{ 
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file. 
    public class Service1 : IService 
    { 
     public Response EchoWithGet(string s) 
     { 
      Response Transaction; 
      Transaction = new Response(); 
      Transaction.AdditionalInfo = "I've responded: " + s; 
      return Transaction; 
     } 
     public Response EchoWithPost(string s) 
     { 
      Response Transaction; 
      Transaction = new Response(); 
      Transaction.AdditionalInfo = "I've responded: " + s; 
      return Transaction; 
     } 
    } 
} 

La configuración es también un poco de misterio para mí. Intenté crear un enlace como se describió en uno de los temas de MSDN: http://msdn.microsoft.com/en-us/library/aa395208.aspx

pero después de invocar un método, devolví una estructura de fallas similar a SOAP pero sin el sobre SOAP.

De todos modos aquí está el config:

<system.serviceModel> 
     <services> 
     <service name="RESTService.Service1"> 
      <host> 
      </host> 
      <endpoint 
       address="rest" behaviorConfiguration="webBehavior" 
       bindingConfiguration="" binding="webHttpBinding" 
       contract="RESTService.IService"/> 
     </service> 
     </services> 
     <behaviors> 
     <endpointBehaviors> 
      <behavior name="webBehavior"> 
       <webHttp /> 
      </behavior> 
     </endpointBehaviors> 
     </behaviors> 
</system.serviceModel> 

Cuando invoco un método de servicio en mi navegador como esto:

http://localhost:2443/Service1.svc/rest/EchoWithGet?s=test

llegué en mi navegador un archivo XML:

<Response ResponseParam1="0"> 
<AdditionalInfo>I've responded: test</AdditionalInfo> 
</Response> 

Parece que estoy en el camino correcto? Sin embargo, todavía no sé cómo recibir una información completa (como la de ASP .NET 2.0) sobre lo que se ha enviado y lo que se ha recibido. Me gustaría no escuchar el puerto de servicio con sniffer para ver qué está pasando por HTTP. Me gustaría verlo. Además, cuando miro el archivo de origen del XML recibido veo esto:

<?xml version="1.0" encoding="utf-8"?><Response ResponseParam1="0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <br/> 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><br/> 
<AdditionalInfo>I've responded: test</AdditionalInfo></Response> 

no quiero tener esta información adicional en el XML devuelto, cómo cortar esto?

Otro problema es con el segundo método:

http://localhost:2443/Service1.svc/rest/EchoWithPost?s=test

Esto no funciona como se esperaba. Aparece el mensaje de error que dice "el método no está permitido". ¿Cómo resolver esto?

Por lo tanto, vamos a resumir esta larga pregunta.

Tengo una solución que funciona a medias, que podría ser la correcta o incorrecta. Me gustaría pedirle que lo termine, que también podría:

  1. Acepte en el método un archivo XML como parámetro.
  2. Mostrarme cómo llamar al método en el navegador web con XML como parámetro.Sí, no quiero un cliente separado en .NET. Deje que el navegador sea el cliente.
  3. Mostrarme cómo cortar la información innecesariamente inflada en XML devuelto.
  4. Mostrarme cómo obtener la descripción de mi servicio .NET 2.0 teniendo en cuenta que no quiero tener SOAP.
  5. Explícame qué está mal con el método EchoWithPost. ¿Por qué no funciona?

Si mi ejemplo es malo, proporcione ejemplos básicos de cómo se debe lograr.

Acabo de aprender .NET y WCF y estoy muy confundido. Todos esos problemas solo con configurar el protocolo de intercambio de datos correcto ... y ni siquiera he estado escribiendo un servicio real: |

Muchas gracias por su tiempo y cualquier ayuda futura.

+0

@wozdu: estás totalmente en el camino correcto; Mire ese screencast en "Plain Old XML" con los servicios WCF REST: le permite hacer todo lo que quiera (devolver un XML totalmente personalizado con solo los elementos y atributos que desee). –

Respuesta

6

El servicio que tiene aquí devolverá un mensaje SOAP - que contendrá el "Tipo Compuesto" como su "carga útil".

WCF por defecto utiliza SOAP - cualquiera de los basicHttpBinding, wsHttpBinding, etc. netTcpBinding todo el trabajo con SOAP como su base.

Si desea devolver XML directamente, debe verificar las capacidades REST de WCF; esto funciona con el webHttpBinding (y solo con ese enlace).

También, cómo producir un XML como esto (sobre la base de un contrato de datos):

<CompositeType BoolValue = 0 StringValue = ""> 

en lugar de esto:

<CompositeType> 
    <BoolValue>0</BoolValue> 
    <StringValue></StringValue> 
</CompositeType> 

Esto es una limitación del serializador WCF DataContract. Por motivos de rendimiento, no admite atributos, p. no puedes crear el primer fragmento de XML que quieras.

Si absolutamente debe tener el primer XML, tendrá que usar el XmlSerializer en su lugar (que tiene su propio conjunto de limitaciones/problemas).

Marc

ACTUALIZACIÓN: si sólo desea devolver un XML en cuestión, entonces usted está probablemente mejor con el enfoque REST.

Consulte el sitio web de Pluralsight para obtener un excelente series of screencasts on using REST y, en particular, un screencast sobre cómo crear un plain-old XML (POX) REST service.

+0

Gracias marc_s, pero ¿cómo puedo usar REST con XMLSerializer? ¿Estás diciendo que para cumplir esta sencilla tarea tengo que abandonar los Contratos? es posible? – Wodzu

+0

No, aún puede usar contratos, pero use el Serializador XML en lugar de DataContractSerializer, si realmente ** DEBE ** tener el formato que está buscando. Pero esto seguirá siendo una respuesta SOAP. –

+0

marc_s: Gracias. La especificación no dice nada sobre SOAP. Así que supongo que necesito enviar y recibir solo un XML sin ningún sobre. Este XML necesita tener atributos como lo he mostrado en mi pregunta. ¿Puedo pedirle que me muestre cómo usar XMLSerializer? Esta es la quinta hora que estoy gastando en buscar una respuesta y estoy tan frustrado;) – Wodzu

0

Eche un vistazo a Enunciate. Lo he usado antes para crear una interfaz REST (XML & & JSON), así como una interfaz SOAP. Puede darte exactamente lo que estás buscando y es muy fácil trabajar con él. El desarrollador principal también es bastante activo en la lista de correo, por lo que si tiene alguna pregunta, simplemente envíe un mensaje al grupo y, por lo general, obtendrá una respuesta muy rápidamente.

+0

Gracias Randyaa, se verá en eso. – Wodzu

Cuestiones relacionadas