Necesito ayuda con la envoltura de un XML en un sobre SOAP para un tercero servidor SOAP. La tercera parte no ha proporcionado archivos xsd para la solicitud entrante y saliente de la respuesta. He tomado los archivos XSD y crea clases de C# de ellos con la herramienta xsd. Mi problema es que tengo que envolver el serializado solicitud con un sobre SOAP y no sé por dónde empezar. Estaba mirando en la Web de Microsoft Mejoras en los Servicios, 3), sino que dice que es sólo para .net 2.0 y VS2005. Yo estoy usando el VS2012 y .net 4.5. También, he mirado en la conexión al servidor por medio de web service pero no parece compatible y no tiene un WSDL.

El siguiente es un ejemplo de lo que el JABÓN de espera de servidor para una solicitud entrante.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<GetBasicData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="CRS610MI">
<CONO xmlns="">1</CONO>
<CUNO xmlns="">12345</CUNO>
</GetBasicData>
</soap:Body>
</soap:Envelope>

Esto es lo que el XML serializado cadena parece.

<?xml version="1.0" encoding="utf-8"?>
<GetBasicData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="CRS610MI">
<CONO xmlns="">1</CONO>
<CUNO xmlns="">12345</CUNO>
</GetBasicData>

Código que estoy usando para mi web de solicitud y respuesta.

Byte[] byteArray = System.Text.UTF8Encoding.UTF8.GetBytes(data);

WebRequest webRequest = WebRequest.Create(@"http://myserver:8888");
webRequest.ContentLength = byteArray.Length;
webRequest.ContentType = @"text/xml; charset=utf-8";
webRequest.Headers.Add("SOAPAction", @"http://schemas.xmlsoap.org/soap/envelope/");
webRequest.Method = "POST";

Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(byteArray, 0, byteArray.Length);
requestStream.Close();
requestStream.Dispose();

WebResponse webResponse = webRequest.GetResponse();

Stream responseStream = webResponse.GetResponseStream();

StreamReader streamReader = new StreamReader(responseStream);

String line;

while ((line = streamReader.ReadLine()) != null)
{
    Debug.WriteLine(line);
}

He probado el código en sustitución de mi cadena serializada con el texto en el archivo de ejemplo proporcionados por el tercero y funcionó como se esperaba. Yo también llevé a mis cadena serializada y se inserta el texto de sobres en los lugares correctos y que también trabajaba en la web de solicitud pasó y me dieron la respuesta que estaba buscando. Corto de insertar el texto de sobres en mi cadena serializada manualmente lo que puedo hacer. Tengo que imaginar que hay un método o clase que se encargará de esta para mí en una forma estandarizada?

El «modo estándar» es para el servicio de un WSDL.
Por CIERTO, eres de los seguro no hay WSDL para el servicio? Trate de usar un navegador y vaya a la dirección del servicio. Si eso no funciona, trate de añadir ?wsdl a la final de la dirección URL del servicio.

OriginalEl autor Matthew | 2014-02-26

4 Comentarios

  1. 2

    Si el proveedor no proporciona un WSDL, entonces usted no debe hacer negocios con ellos. No es ciencia de cohetes, y es el estándar de manera que los servicios web SOAP trabajo. Solo ha habido una standard durante más de una década. Yo le pregunto seriamente en lo que de otra manera este proveedor de servicios es incompetente.

    Si usted no tiene ninguna opción pero para hacer negocios con incompetente socios de negocios, a continuación,

    1. Buena suerte a usted
    2. Crear su propio WSDL para que coincida con su servicio, a continuación, utilizar «Agregar Referencia de Servicio de» crear las clases de proxy necesario para comunicarse con el servicio.
    Sí me doy cuenta de esto. Este es un viejo servicio que no ha sido actualizado en mucho tiempo, pero todavía funciona. Hay una alternativa, que es llamar a la api directamente y, a continuación, analizar los campos de un único y enorme cadena de la línea que no tiene la documentación en cuanto a lo que cada valor es. Así menor de dos males, supongo.
    ¿Por qué necesita ser actualizado? ¿Por qué no tener un WSDL para empezar? Quiero decir, realmente, WSDL, ha sido parte de JABÓN desde el principio. Tal vez perdieron el WSDL? O, si usted sabe que el servicio lo suficientemente bien como para tratar de simular hasta un sobre en la mano, tal vez usted puede crear un WSDL que va a hacer la misma cosa? Entonces se puede dar el proveedor de servicios el don del WSDL.
    A veces el uso de la cruda jabón intercambio es necesario cuando el WSDL está resultando ser otro fracaso de interoperabilidad entre Java y .NET, y usted puede hacer el médico para que lo cambie porque «funciona en soapUI y eclipse».

    OriginalEl autor John Saunders

  2. 2

    He podido resolver mediante el uso de un XLST para envolver el XML de soap.

    Aquí está mi prueba de trabajo de código de la aplicación

    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Xml.XPath;
    using System.Xml.Xsl;
    namespace ConsoleApplication2
    {
    class Program
    {
    static void Main(string[] args)
    {
    GetBasicData getBasicData = new GetBasicData();
    getBasicData.CONO = "1";
    getBasicData.CUNO = "201702";
    XPathDocument requestXPathDocument;
    if (SerializeIntoRequestXPathDocument(getBasicData, out requestXPathDocument))
    {
    XmlDocument requestXmlDocument;
    if (CreateRequestXMLDocument(requestXPathDocument, @"Z:\Darice\M3 SOAP\GetBasicData.xsl", out requestXmlDocument))
    {
    XmlDocument responseXmlDocument;
    if (ExecuteRequestSoap(requestXmlDocument, out responseXmlDocument))
    {
    MemoryStream unwrappedMemoryStream;
    if (UnwrapSoapResponseXmlDocumentIntoMemoryStream(responseXmlDocument, out unwrappedMemoryStream))
    {
    GetBasicDataResponse getBasicDataResponse;
    if (!DeserializeResponseMemoryStream(unwrappedMemoryStream, out getBasicDataResponse))
    {
    Debug.WriteLine("FAIL");
    }
    }
    }
    }
    }
    Console.ReadLine();
    }
    //STATIC FUNCTIONS
    private static Boolean CreateRequestXMLDocument(XPathDocument xPathDocument, String xslPath, out XmlDocument xmlDocument)
    {
    try
    {
    using (MemoryStream memoryStream = new MemoryStream())
    {
    using (StreamWriter streamWriter = new StreamWriter(memoryStream))
    {
    XmlWriter xmlWriter = XmlWriter.Create(streamWriter);
    XsltSettings xsltSettings = new XsltSettings();
    xsltSettings.EnableScript = true;
    XslCompiledTransform xslCompiledTransform = new XslCompiledTransform();
    xslCompiledTransform.Load(xslPath, xsltSettings, null);
    xslCompiledTransform.Transform(xPathDocument, xmlWriter);
    memoryStream.Position = 0;
    using (StreamReader streamReader = new StreamReader(memoryStream))
    {
    XmlReader xmlReader = XmlReader.Create(streamReader);
    xmlDocument = new XmlDocument();
    xmlDocument.Load(xmlReader);
    }
    }
    }
    }
    catch (Exception exception)
    {
    Debug.WriteLine(exception);
    xmlDocument = null;
    return false;
    }
    return true;
    }
    private static Boolean DeserializeResponseMemoryStream<T>(MemoryStream memoryStream, out T xmlObject)
    {
    try
    {
    using (StreamReader streamReader = new StreamReader(memoryStream))
    {
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    using (XmlReader xmlReader = XmlReader.Create(streamReader))
    {
    xmlObject = (T)xmlSerializer.Deserialize(xmlReader);
    }
    }
    }
    catch (Exception exception)
    {
    Debug.WriteLine(exception);
    xmlObject = default(T);
    return false;
    }
    return true;
    }
    private static Boolean ExecuteRequestSoap(XmlDocument requestXmlDocument, out XmlDocument responseXmlDocument)
    {
    try
    {
    Byte[] byteArray = UTF8Encoding.UTF8.GetBytes(requestXmlDocument.OuterXml);
    WebRequest webRequest = WebRequest.Create(Properties.Resources.SoapServerAddress);
    webRequest.ContentLength = byteArray.Length;
    webRequest.ContentType = @"text/xml; charset=utf-8";
    webRequest.Headers.Add("SOAPAction", @"http://schemas.xmlsoap.org/soap/envelope/");
    webRequest.Method = "POST";
    using (Stream requestStream = webRequest.GetRequestStream())
    {
    requestStream.Write(byteArray, 0, byteArray.Length);
    using (WebResponse webResponse = webRequest.GetResponse())
    {
    using (Stream responseStream = webResponse.GetResponseStream())
    {
    using (StreamReader streamReader = new StreamReader(responseStream))
    {
    responseXmlDocument = new XmlDocument();
    responseXmlDocument.LoadXml(streamReader.ReadToEnd());
    }
    }
    }
    }
    }
    catch (Exception exception)
    {
    Debug.WriteLine(exception);
    responseXmlDocument = null;
    return false;
    }
    return true;
    }
    private static Boolean SerializeIntoRequestXPathDocument<T>(T dataObject, out XPathDocument xPathDocument)
    {
    try
    {
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    using (MemoryStream memoryStream = new MemoryStream())
    {
    using (StreamWriter streamWriter = new StreamWriter(memoryStream))
    {
    xmlSerializer.Serialize(streamWriter, dataObject);
    memoryStream.Position = 0;
    using (StreamReader streamReader = new StreamReader(memoryStream))
    {
    memoryStream.Position = 0;
    xPathDocument = new XPathDocument(streamReader);
    }
    }
    }
    }
    catch (Exception exception)
    {
    Debug.WriteLine(exception);
    xPathDocument = null;
    return false;
    }
    return true;
    }
    private static Boolean UnwrapSoapResponseXmlDocumentIntoMemoryStream(XmlDocument responseXmlDocument, out MemoryStream memoryStream)
    {
    try
    {
    XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(responseXmlDocument.NameTable);
    xmlNamespaceManager.AddNamespace("tns", "CRS610MI");
    xmlNamespaceManager.AddNamespace("SOAP", @"http://schemas.xmlsoap.org/soap/envelope/");
    XmlNode xmlNode = responseXmlDocument.SelectSingleNode(@"/SOAP:Envelope/SOAP:Body/tns:GetBasicDataResponse", xmlNamespaceManager);
    memoryStream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(xmlNode.OuterXml));
    }
    catch (Exception exception)
    {
    Debug.WriteLine(exception);
    memoryStream = null;
    return false;
    }
    return true;
    }
    }
    }

    Y aquí está el código XSL

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:crs="CRS610MI" exclude-result-prefixes="crs">
    <xsl:output method="xml"/>
    <xsl:template match="/">
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <soap:Body>
    <xsl:apply-templates select="node()|@*"/>
    </soap:Body>
    </soap:Envelope>
    </xsl:template>
    <xsl:template match="node()|@*">
    <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>

    OriginalEl autor Matthew

  3. 1

    No entiendo por qué algunos son tan firme que se TIENE que utilizar el WSDL. El WSDL es simplemente para que usted puede llamar a sus métodos, y el uso de sus entidades, y es opcional.

    He llegado al trabajo por ir a la url exacta para su servicio, tales como
    https://something.com/SomeService/TheService.asmx?method=DoSomething

    Y tan solo analizar exactamente la cabecera XML y su API define, incluyendo la envoltura SOAP. La primera sección debería ser la información de encabezado y, a continuación, a continuación, que es el XML. Crear el XML exactamente cómo especificar, incluyendo los sobres etiquetas. Para el Encabezado: PUBLICAR, alojar, Tipo de Contenido y SOAPAction, son los más importantes. He encontrado que algunos servidores no necesitan Contenido de Longitud, aunque su lista en su API.

    Aquí está el código de ejemplo

    public void PostXMLData(string serviceUrl, XDocument requestXML)
    {
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(serviceUrl);
    req.Method = "POST";
    req.Host = "SOMETHING";
    req.ContentType = "text/xml; charset=utf-8";
    req.Headers.Add("SOAPAction", "SOMETHING");
    req.Accept = "text/xml";
    using (Stream stream = req.GetRequestStream())
    {
    requestXML.Save(stream);
    }
    using (WebResponse resp = req.GetResponse())
    {
    using (StreamReader rd = new StreamReader(resp.GetResponseStream()))
    {
    var result = rd.ReadToEnd();
    if (result.Contains("error"))
    {
    throw new Exception($"XML Submission Failed: {result}");
    }
    }
    }
    }

    OriginalEl autor Mauro Torres

  4. 0

    Usted necesita para marcar su clase con MessageContract para el jabón

    [MessageContract]
    public class ExampleResponse
    {
    private string _myResponse = String.Empty;
    [MessageBodyMember(Name = "ResponseToGive", Namespace = "http://myserver:8888")]
    public string ResponseToGive
    {
    get { return _myResponse; }
    set { _myResponse = value; }
    }
    }
    He intentado añadir el contrato de mensaje y el cuerpo del mensaje los miembros de las propiedades, pero la cadena serializada tiene el mismo aspecto que tenía antes. Estoy usando el serializador de XML, debo usar algo más?
    No estoy en frente de una PC así que no te puedo dar impone, sin embargo, si buscas en google c# Mensaje soap.CreateMessage verá qué hacer.

    OriginalEl autor TYY

Dejar respuesta

Please enter your comment!
Please enter your name here