如何在没有任何格式的情况下使用 XmlElement.InnerXml?
How to use XmlElement.InnerXml WITHOUT any formatting?
我需要通过 XML 与 WebService 通信。此服务使用 saml:Assertion 来验证连接。我可以与服务器通信,但验证总是失败。我搜索了几个小时是什么问题,因为当我使用具有完全相同参数和 saml 票证的 soapUI 时,它就可以工作。我试图 "manually" 删除 saml:Assertion 中的任何格式,因为它已签名,因此通过单字节更改,它将不再起作用。
这是我的代码:
// Insert saml:Assertion string into soapenv:Header
private static void InsertSAML(ref XmlDocument soapXML, ref XmlNamespaceManager nsmgr, string saml)
{
// Remove all formatting
saml = saml.Replace("\r", "");
saml = saml.Replace("\n", "");
while(saml.IndexOf(" ") > -1)
{
saml = saml.Replace(" ", " ");
}
saml = saml.Replace("> <", "><");
saml = saml.Replace("\" />", "\"/>");
XmlElement soapHeader = (XmlElement)soapXML.SelectSingleNode("//soapenv:Envelope/soapenv:Header/wsse:Security", nsmgr);
if (soapHeader == null)
{
throw new Exception("Can't find \"//soapenv:Envelope/soapenv:Header/wsse:Security\"");
}
soapHeader.InnerXml += saml;
}
但是当我使用 soapHeader.InnerXml += saml;
时似乎会导致某种格式设置。没有内部内容的元素结束标签前会出现空格:
所以,我需要添加这个:
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
但最终 XML 看起来像这样,即使我在插入之前替换了这些事件:
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
我怎样才能摆脱这种行为?
正如我所说,问题在于当我将内容附加到 InnerXml 时,额外的字节 XmlDocument 添加到我的 xml。我非常努力地删除所有格式,这是一个很好的方向。但是我没有 "un-formatting" saml:Assertion 部分,而是在将其发送到服务之前取消格式化整个请求正文。现在它起作用了。我在发送请求之前调用了这个方法:
// Insert XML to request body
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (var stringWriter = new StringWriter())
using (var xmlTextWriter = XmlWriter.Create(stringWriter))
using (Stream stream = webRequest.GetRequestStream())
{
// Get XML contents as string
soapEnvelopeXml.WriteTo(xmlTextWriter);
xmlTextWriter.Flush();
string str = stringWriter.GetStringBuilder().ToString();
// Remove all formatting
str = str.Replace("\r", "");
str = str.Replace("\n", "");
while (str.IndexOf(" ") > -1)
{
str = str.Replace(" ", " ");
}
str = str.Replace("> <", "><");
str = str.Replace("\" />", "\"/>");
// Write the unbeutified text to the request stream
MemoryStream ms = new MemoryStream(UTF8Encoding.Default.GetBytes(str));
ms.WriteTo(stream);
}
}
我需要通过 XML 与 WebService 通信。此服务使用 saml:Assertion 来验证连接。我可以与服务器通信,但验证总是失败。我搜索了几个小时是什么问题,因为当我使用具有完全相同参数和 saml 票证的 soapUI 时,它就可以工作。我试图 "manually" 删除 saml:Assertion 中的任何格式,因为它已签名,因此通过单字节更改,它将不再起作用。
这是我的代码:
// Insert saml:Assertion string into soapenv:Header
private static void InsertSAML(ref XmlDocument soapXML, ref XmlNamespaceManager nsmgr, string saml)
{
// Remove all formatting
saml = saml.Replace("\r", "");
saml = saml.Replace("\n", "");
while(saml.IndexOf(" ") > -1)
{
saml = saml.Replace(" ", " ");
}
saml = saml.Replace("> <", "><");
saml = saml.Replace("\" />", "\"/>");
XmlElement soapHeader = (XmlElement)soapXML.SelectSingleNode("//soapenv:Envelope/soapenv:Header/wsse:Security", nsmgr);
if (soapHeader == null)
{
throw new Exception("Can't find \"//soapenv:Envelope/soapenv:Header/wsse:Security\"");
}
soapHeader.InnerXml += saml;
}
但是当我使用 soapHeader.InnerXml += saml;
时似乎会导致某种格式设置。没有内部内容的元素结束标签前会出现空格:
所以,我需要添加这个:
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
但最终 XML 看起来像这样,即使我在插入之前替换了这些事件:
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
我怎样才能摆脱这种行为?
正如我所说,问题在于当我将内容附加到 InnerXml 时,额外的字节 XmlDocument 添加到我的 xml。我非常努力地删除所有格式,这是一个很好的方向。但是我没有 "un-formatting" saml:Assertion 部分,而是在将其发送到服务之前取消格式化整个请求正文。现在它起作用了。我在发送请求之前调用了这个方法:
// Insert XML to request body
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (var stringWriter = new StringWriter())
using (var xmlTextWriter = XmlWriter.Create(stringWriter))
using (Stream stream = webRequest.GetRequestStream())
{
// Get XML contents as string
soapEnvelopeXml.WriteTo(xmlTextWriter);
xmlTextWriter.Flush();
string str = stringWriter.GetStringBuilder().ToString();
// Remove all formatting
str = str.Replace("\r", "");
str = str.Replace("\n", "");
while (str.IndexOf(" ") > -1)
{
str = str.Replace(" ", " ");
}
str = str.Replace("> <", "><");
str = str.Replace("\" />", "\"/>");
// Write the unbeutified text to the request stream
MemoryStream ms = new MemoryStream(UTF8Encoding.Default.GetBytes(str));
ms.WriteTo(stream);
}
}