Reputation: 2125
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>
Upvotes: 0
Views: 1875
Reputation: 26213
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">
Upvotes: 1