【问题标题】:C# SOAP Service Remove xmlns="" From Header ElementC# SOAP 服务从标题元素中删除 xmlns=""
【发布时间】:2015-07-02 13:15:19
【问题描述】:

我使用服务引用从提供的 WSDL 生成 SOAP 客户端。除了导致服务失败的标头元素上的空白 xmlns 之外,一切都很好。使用 SOAPUI,我知道如果我从元素中删除它,请求就可以正常工作。如何以编程方式从属性中删除此空白 xmlns?由于这是从外部应用程序加载的 DLL,因此我没有使用 app.config。

SecurityHeaderType 是一个生成的对象,由 h:Security 元素及其对应的命名空间组成。 SecurityHeaderType 中有一个名为 Any 的 XmlElement[],这是我设置元素的位置。

private SecurityHeaderType GetSecurityHeaderType()
    {
        SecurityHeaderType securityHeader = new SecurityHeaderType();

        DateTime created = DateTime.Now;

        string creationDate;
        creationDate = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");

        string nonce = nonce = (new Random().Next(0, int.MaxValue)).ToString();

        byte[] hashedPassword;
        hashedPassword = GetSHA1(password);

        string concatednatedDigestInput = string.Concat(nonce, creationDate, Encoding.Default.GetString(hashedPassword));
        byte[] digest;
        digest = GetSHA1(concatednatedDigestInput);

        string passwordDigest;
        passwordDigest = Convert.ToBase64String(digest);

        string encodedNonce;
        encodedNonce = Convert.ToBase64String(Encoding.Default.GetBytes(nonce));

        XmlDocument doc = new XmlDocument();
        using (XmlWriter writer = doc.CreateNavigator().AppendChild())
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("Security");
            writer.WriteStartElement("UsernameToken");
            writer.WriteElementString("Username", username);
            writer.WriteElementString("Password", passwordDigest);
            writer.WriteElementString("Nonce", encodedNonce);
            writer.WriteElementString("Created", creationDate);
            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Flush();
        }

        doc.DocumentElement.RemoveAllAttributes();
        System.Xml.XmlElement[] headers = doc.DocumentElement.ChildNodes.Cast<XmlElement>().ToArray<XmlElement>();

        securityHeader.Any = headers;

        return securityHeader;


    }

当我在客户端调用一个方法时,每个请求都必须有上面的头,但它实际上是在生成下面的XML;

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
    <h:Security xmlns:h="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <UsernameToken xmlns="">
            <Username></Username>
            <Password></Password>
            <Nonce></Nonce>
            <Created></Created>
        </UsernameToken>
    </h:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <createShipmentRequest>
        <requestedShipment>
            <customerReference>Customer Ref</customerReference>
        </requestedShipment>
    </createShipmentRequest>
</s:Body>

不管我把什么作为第一个元素放在 Security 元素中,它总是会自动以 xmlns="" 出现。

我想简单地获取它,以便发出以下请求并且 usernameToken 元素没有我知道可以正常工作的空白命名空间;

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
    <h:Security xmlns:h="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <UsernameToken>
            <Username></Username>
            <Password></Password>
            <Nonce></Nonce>
            <Created></Created>
        </UsernameToken>
    </h:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <createShipmentRequest>
        <requestedShipment>
            <customerReference>Customer Ref</customerReference>
        </requestedShipment>
    </createShipmentRequest>
</s:Body>

【问题讨论】:

    标签: c# soap


    【解决方案1】:

    你需要包含默认命名空间,所以:

    writer.WriteStartElement("UsernameToken", 
        "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    

    等等。您的“正确”XML 中的所有这些元素都具有此命名空间,因为它们从 h:Security 中的声明中指定的默认命名空间继承它:

    <h:Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    

    【讨论】:

    • 我不相信。我之前尝试过,它所做的只是在 UsernameToken 元素上输出 ns 导致它失败。刚刚重试,它现在完全按照需要输出,没有 ns。浪费了一个上午!感谢您的快速回复。
    猜你喜欢
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多