如何在没有任何格式的情况下使用 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);
    }
}