Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
513 views
in Technique[技术] by (71.8m points)

c# - Wrap XML in SOAP envelope in .net

I need help with wrapping an XML in a SOAP envelope for a third party SOAP server. The third party has provided xsd files for the inbound request and outbound response. I've taken those XSD files and created C# classes of them using the xsd tool. My problem is that I need to wrap the serialized request with a SOAP envelope and I don't know where to start. I was looking at the Microsoft Web Service Enhancements 3, but that says that it's only for .net 2.0 and VS2005. I am using VS2012 and .net 4.5. Also, I've looked into connecting to the server by way of web service but it doesn't seem compatible and does not have a WSDL.

The following is a sample of what the SOAP server expects for an inbound request.

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

This is what the serialized XML string looks like.

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

Code I'm using for my web request and response.

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

I've tested my code by replacing my serialized string with the text in the sample file provided by the third party and it worked as expected. I also took my serialized string and inserted the envelope text in the correct places and that also worked, web request went through and I got the response I was looking for. Short of inserting the envelope text into my serialized string manually what can I do. I have to imagine there's a method or class that will take care of this for me in a standardized way?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I was able to solve this by using an XLST to wrap the XML in soap.

Here's my working test app code

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:DariceM3 SOAPGetBasicData.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;
        }
    }
}

And here's the XSL code

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...