XML wrapping in .apap envelope in .net

I need help migrating XML in a SOAP envelope to a third-party SOAP server. A third party provided xsd files for the incoming request and the outgoing response. I took these XSD files and created their C # classes 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 Microsoft Web Service Enhancements 3, but this suggests that it is only for .net 2.0 and VS2005. I am using VS2012 and .net 4.5. In addition, I learned how to connect to the server using a web service, but it does not seem compatible and does not have WSDL .

The following is an example of what a SOAP server expects for an incoming 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 a 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> 

The code I use 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 tested my code by replacing my serialized string with text in an example file provided by a third party, and it worked as expected. I also took my serialized string and inserted the envelope text in the correct places, and it also worked, the web request went through, and I got the answer I was looking for. If you don’t enter the envelope text in my serialized string manually, what can I do. Should I imagine a method or class that takes care of this for me in a standard way?

+4
source share
3 answers

I was able to solve this problem using XLST to transfer XML to soap.

Here is my working test application 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:\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; } } } 

And here is 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> 
+1
source

If your service provider does not provide WSDL, you should not deal with them. This is not rocket science, and it is the standard way SOAP web services work. This has been the standard for over a decade. I seriously wonder how this service provider is incompetent.

If you have no choice but to do business with incompetent business partners, then

  • Good luck to you.
  • Create your own WSDL to match their service, and then use the "Add Service Link" to create the proxy classes needed to communicate with this service.
+4
source

You need to mark your MessageContract class for soap

 [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; } } } 
0
source

Source: https://habr.com/ru/post/1272751/


All Articles