草庐IT

c# - 在 .net 中将 XML 包装在 SOAP 信封中

coder 2024-06-27 原文

我需要帮助将 XML 包装在第三方 SOAP 服务器的 SOAP 信封中。第三方已经为入站请求和出站响应提供了xsd文件。我获取了这些 XSD 文件并使用 xsd 工具为它们创建了 C# 类。我的问题是我需要用 SOAP 信封包装序列化请求,但我不知道从哪里开始。我正在查看 Microsoft Web Service Enhancements 3,但上面说它仅适用于 .net 2.0 和 VS2005。我正在使用 VS2012 和 .net 4.5。此外,我研究过通过 Web 服务连接到服务器,但它似乎不兼容并且没有 WSDL

以下是 SOAP 服务器对入站请求的期望示例。

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

这是序列化的 XML 字符串的样子。

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

我用于网络请求和响应的代码。

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

我已经通过用第三方提供的示例文件中的文本替换我的序列化字符串来测试我的代码,它按预期工作。我还获取了我的序列化字符串并将信封文本插入到正确的位置,这也奏效了,网络请求通过了,我得到了我正在寻找的响应。除了手动将信封文本插入我的序列化字符串外,我还能做什么。我必须想象有一个方法或类可以以标准化的方式为我处理这个问题?

最佳答案

我能够通过使用 XLST 将 XML 包装在 soap 中来解决这个问题。

这是我的工作测试应用程序代码

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

这是 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>

关于c# - 在 .net 中将 XML 包装在 SOAP 信封中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22053998/

有关c# - 在 .net 中将 XML 包装在 SOAP 信封中的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  4. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  5. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  6. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  7. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  8. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  9. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  10. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

随机推荐