【问题标题】:How to use XmlElement.InnerXml WITHOUT any formatting?如何在没有任何格式的情况下使用 XmlElement.InnerXml?
【发布时间】:2017-08-16 09:06:08
【问题描述】:

我需要通过 XML 与 WebService 进行通信。该服务使用 saml:Assertion 来验证连接。我可以与服务器通信,但验证总是失败。我搜索了几个小时问题出在哪里,因为当我使用具有完全相同参数和 saml 票证的soapUI 时,它可以工作。我尝试“手动”从 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" />

我怎样才能摆脱这种行为?

【问题讨论】:

  • 你为什么认为是格式化失败了?使用诸如wireshark 或fiddler 之类的嗅探器并将soapUI 响应与您的应用程序响应进行比较。它们使您的应用程序看起来像soapUI。首先比较第一个请求并修改您的 c# 代码,以便标头与soapUI 相同。
  • 一定是格式。来自soapUI 和我的C# 代码的请求具有完全相同的标题和正文,除了关闭( /> )单个标签之前的空格。
  • 如果标题和正文相同,您将如何调用格式?第一反应是一样的吗?都使用http 1.0吗?您是否获得了 200 完成状态?如果数据完全相同,我认为这将是一个时间问题。 http 使用 tcp 作为传输层,可能存在 tcp 断开连接。但我不这么认为。这更像是您同时打开了两个连接,而服务器不允许第二个连接。
  • 我从 WebService 得到了明确的响应。没有连接问题,请求已发送,并从我要访问的服务器收到响应。问题是,我收到一条错误消息(来自该服务器的编码响应),表明我的 saml 无效。这是真的,我的 saml:Assertion 不能有效,其中有额外的空格。 saml 是一个签名的指纹,如果一个字节被修改,它就不再有效。我只想知道如何在没有额外空格的情况下将它插入到我的 xml 中。
  • 必须在对正文进行所有编辑后进行签名。空间和返回应该被加密然后解密并且不应该有任何区别。所以我不知道你为什么要删除空格。您在 c# 中使用的加密(签名)方法与服务器使用的解密不同。

标签: c# xml formatting saml xmldocument


【解决方案1】:

正如我所说,当我将内容附加到 InnerXml 时,问题在于添加到我的 xml 中的额外字节 XmlDocument。我非常努力地删除所有格式,这是一个很好的方向。但是,我没有“取消格式化” 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);
    }
}

【讨论】:

    猜你喜欢
    • 2013-04-02
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2012-09-30
    相关资源
    最近更新 更多