简体   繁体   中英

C# SOAP Service Remove xmlns=“” From Header Element

I have used a Service Reference to generate a SOAP client from a provided WSDL. All is fine apart a blank xmlns on an element in the header which is causing the service to fail. Using SOAPUI, I know that if I remove the it from the element, the request works fine. How can I programatically remove this blank xmlns from the attribute? As this is a DLL being loaded in from an external application I am not using app.config.

SecurityHeaderType is a generated object which consists of the h:Security element and it's corresponding namespaces. There is a XmlElement[] with the name of Any within SecurityHeaderType which is where I set the elements.

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;


    }

when I call a method on the client, every request must have the above headers, but it's actually generating the following 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>

It doesn't matter what I put as the first element within the Security element, it always automatically comes out with xmlns="".

I would like to simply get it so that the following request is made and the usernameToken element does not have a blank namespace which I know works fine;

<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>

You need to include the default namespace, so:

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

And so on. All of those elements in your 'correct' XML have this namespace, as they inherit it from the default namespace as specified in the declaration in h:Security :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM