I am sending WCF request and each request is required to have custom header - attributes with Username and Password must be added to each request. I’ve successfully done that with only one exception - I don’t know how to add namespace before rendered class name and properties. It should be like this (rendered xml) - wsse is before attributes names:
<wsse:UsernameToken xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<wsse:Username>test</wsse:Username>
<wsse:Password Type="wsse:PasswordText">test1</wsse:Password>
</wsse:UsernameToken>
However, adding namespace to DataContract does not render like this, but like this - namespace wsse is not before class name, but inside tag, as attribute - xmlns=“wsse”. How to make namespace before class name and before attributes name? I am getting ‘bad request’ error from the server:
<UsernameToken xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Password xmlns="wsse">test1</Password>
<Username xmlns="wsse">test</Username>
</UsernameToken>
This is what customer wants to be generated - wsse namespace is before UsernameToken and both properties:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="http://siebel.com/CustomUI" xmlns:mtel="http://www.siebel.com/xml/Mtel%20Order%20Integration">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
<wsse:UsernameToken xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<wsse:Username>test</wsse:Username>
<wsse:Password Type="wsse:PasswordText">test</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
This is how code is generated - before UsernameToken and it’s properties is no namespace, it is inside both tags as xmlns=“wsse” and I believe this is the reason for error:
<s:Header>
<a:Action s:mustUnderstand="1">document/http://siebel.com/CustomUI:UpsertProvisioningStatusData</a:Action>
<a:MessageID>urn:uuid:e5896c20-1eec-4171-a4a3-5d5ea52aa75c</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<UsernameToken xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Password xmlns="wsse">test1</Password>
<Username xmlns="wsse">test</Username>
</UsernameToken>
</s:Header>
Class for UsernameToken:
[DataContract(Namespace = "wsse")]
public class UsernameToken
{
[DataMember]
public string Username { get; set; }
[DataMember]
public string Password
{
get; set;
}
}
And message inspector, where each message gets custom header:
public class MessageInspector : IClientMessageInspector
{
private static readonly ILog _log = LogManager.GetLogger("WS");
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var property = request.Properties.ContainsKey(HttpRequestMessageProperty.Name) ?
request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty : new HttpRequestMessageProperty();
if (null == property)
return null;
UsernameToken token = new UsernameToken
{
Username = "test",
Password = "test1"
};
request.Headers.Add(MessageHeader.CreateHeader("UsernameToken", "", token));
return null;
}
}