C#编写SOAP消息(生成XML格式编码)

在C#用开发网络应用的时候,我们经常会遇到需要将一个SOAP格式的消息(包括Header)使用HTTP的POST方式发送到某个指定的URL这类问题。

这里总结一下这一技术的的实现方法:.

首先,我们需要创建一个有效的XML文件,可以使用LINQ to XML来实现,

方法一:LINQ to XML来实现编写SOAP消息【推荐方法】

如下:
XNamespace soapenv = "http://schemas.xmlsoap.org/soap/envelope/";
var document = new XDocument(
               new XDeclaration("1.0", "utf-8", String.Empty),
               new XElement(soapenv + "Envelope",
                   new XAttribute(XNamespace.Xmlns + "soapenv", soapenv),
                   new XElement(soapenv + "Header",
                       new XElement(soapenv + "AnyOptionalHeader",
                           new XAttribute("AnyOptionalAttribute", "false"),
                       )
                   ),
                   new XElement(soapenv + "Body",
                       new XElement(soapenv + "MyMethodName",
                            new XAttribute("AnyAttributeOrElement", "Whatever")
                       )
                   )
                );
然后,就可以使用它了:
            var req = WebRequest.Create(uri);
            req.Timeout = 300000;  //timeout
            req.Method = "POST";
            req.ContentType = "text/xml;charset=UTF-8";

            using (var writer = new StreamWriter(req.GetRequestStream()))
            {
                writer.WriteLine(document.ToString());
                writer.Close();
            }
如果,我们还要读取对方服务器返回的消息,那么可以这样:
            using (var rsp = req.GetResponse())
            {
                req.GetRequestStream().Close();
                if (rsp != null)
                {
                    using (var answerReader =
                                new StreamReader(rsp.GetResponseStream()))
                    {
                        var readString = answerReader.ReadToEnd();
                        //do whatever you want with it
                    }
                }
            }

对于如下一段SOAP格式的XML数据,又可以怎么处理呢?
<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <env:Header>
  <NotifySOAPHeader xmlns="http://www.csapi.org/schema/parlayx/common/v2_0">
  <ServiceID>3001400002</ServiceID>
  <SPrevID>fanxiang123</SPrevID>
  <SPrevPassword>12345678</SPrevPassword>
  <TransactionID>01022016400400000025</TransactionID>
  </NotifySOAPHeader>
  </env:Header>
  <env:Body>
  <notifySmsReception xmlns="http://www.csapi.org/schema/parlayx/sms/notification/v2_0/local">
  <registrationIdentifier/>
  <message>
  <message>aaaa</message>
  <senderAddress>tel:+861067453262</senderAddress>
  <smsServiceActivationNumber>tel:10661112</smsServiceActivationNumber>
  </message>
  </notifySmsReception>
  </env:Body>
</env:Envelope>

其实很简单:
XmlDocument xdoc = new XmlDocument();
xdoc.Load("Data.xml");

string s = xdoc.DocumentElement["env:Header"]["NotifySOAPHeader"].InnerXml;
Console.WriteLine(s);

方法二:XmlTextWriter编写SOAP消息

因为SOAP消息是基于XML文档的,因此在C#中可以使用XmlTextWriter编写SOAP消息
首先定义一个XmlTextWriter
st = new MemoryStream(1024);//分配空间
XmlTextWriter tr = new XmlTextWriter(st,Encoding.UTF8);
//初始化一个XmlTextWriter,编码方式为Encoding.UTF8
然后就可以开始写入了

tr.WriteStartDocument();
tr.WriteStartElement("soap","Envelope","http://schemas.xmlsoap.org/soap/envelope/");
tr.WriteAttributeString("xmlns","xsi",null,"http://www.w3.org/2001/XMLSchema-instance");
tr.WriteAttributeString("xmlns","xsd",null,"http://www.w3.org/2001/XMLSchema");
tr.WriteAttributeString("xmlns","soap",null,"http://schemas.xmlsoap.org/soap/envelope/");

tr.WriteStartElement("Header", "http://schemas.xmlsoap.org/soap/envelope/");
tr.WriteStartElement(null, "AuthInfo", "http://tempuri.org/");
tr.WriteElementString("UserName", "admin");
tr.WriteElementString("PassWord", "123");
tr.WriteEndElement();
tr.WriteEndElement();
tr.WriteStartElement("Body","http://schemas.xmlsoap.org/soap/envelope/");
tr.WriteStartElement(null,"GetAccount","http://tempuri.org/");
tr.WriteElementString("acctID","1");
tr.WriteEndElement();         
tr.WriteEndElement(); 
tr.WriteEndDocument();

最后得到的SOAP消息如下:
<?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:Header>
    <AuthInfo xmlns="http://tempuri.org/">
        <UserName>admin</UserName>
        <PassWord>123</PassWord>
    </AuthInfo>
</soap:Header>
<soap:Body>
    <GetAccount xmlns="http://tempuri.org/">
        <acctID>1</acctID>
    </GetAccount>
</soap:Body>
</soap:Envelope>