My problem is that root element is written twice. I would like to delete root element generated by MessageHeader itself:
My code:
var el = XElement.Parse("<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'>TEST1</wsse:Password>" +
"</wsse:UsernameToken>" +
"</wsse:Security>");
request.Headers.Add(MessageHeader.CreateHeader("Security", "wsse", el));
Here, code generated in request header - I would like to remove outer 'Security' node, but I dont' know how:
<Security xmlns="wsse">
<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">TEST1</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</Security>
Since there is no overload for MessageHeader.CreateHeader
, you can just extract it from the parsed structure itself and use its data to create MessageHeader
with it:
var el = XElement.Parse("<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'>TEST1</wsse:Password>" +
"</wsse:UsernameToken>" +
"</wsse:Security>");
string name = el.Name.LocalName;
string xmlns = el.Attributes().Single().Value;
XNode singleChild = el.Nodes().Single();
var h = MessageHeader.CreateHeader(name, xmlns, singleChild);
That should give you the desired result.
Note that MessageHeader.CreateHeader
method forbids using names with ":" sign in it (so no NamespaceName are allowed).
Alright, here is a way to replace what the MessageHeader
outputs with a custom implementation of it:
public sealed class PrefixedMessageHeader(XElement header) : MessageHeader
{
public override string Name => header.Name.LocalName;
public override string Namespace => header.Name.Namespace.NamespaceName;
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteStartElement(header.GetPrefixOfNamespace(header.Name.Namespace), Name, Namespace);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
foreach (XNode node in header.Nodes())
{
using var reader = node.CreateReader();
writer.WriteNode(reader, false);
}
}
}
So, instead of calling MessageHeader.CreateHeader
you can just create initialize new PrefixedMessageHeader(el)
and pass it on to the request.Headers.Add
method.