Search code examples
c#.netweb-serviceswcfsoap

How to set soap message header element namespace explicitly in .NET WCF


I'm trying to create a ClientInspector that will add some data to outgoing SOAP requests and add it as a endpoint behavior for client services. Something like this:

public class InsertHeaderClientInspector : IClientMessageInspector
{

    public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
    {
        var HeaderData = new ProcType()
            {
                attr = _correlation
            };

        MessageHeader header = MessageHeader.CreateHeader("HeaderInfo", "http://schemas.tempuri.fi/process/2016/04/", HeaderData);
        request.Headers.Add(header);

        return null;
    }
}

[System.Xml.Serialization.XmlRootAttribute("HeaderInfo", Namespace = "http://schemas.tempuri.fi/process/2016/04/", IsNullable = false)]
public class ProcType
{
    [XmlElement(Namespace = "")]
    public string attr;
}

Inspector is working fine, but the problem is that generated SOAP message will have namespace for ProcType.attr and I want to remove it.

<s:Header>
    <HeaderInfo xmlns="http://schemas.tempuri.fi/process/2016/04/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <attr xmlns="http://schemas.datacontract.org/2004/07/MyService.Behaviors">asdasd</attr>
    </HeaderInfo>
</s:Header>

Instead it should be like

<s:Header>
    <HeaderInfo xmlns="http://schemas.tempuri.fi/process/2016/04/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <attr">asdasd</attr>
    </HeaderInfo>
</s:Header>

XMLElement attribute I've tried to use does not work. So how do I remove this unnecessary namespace?


Solution

  • I ended up fixing this issue by creating custom header element which I insert to request.

    public class ProcessGuidHeader : MessageHeader
    {
        private string _attr;
        private string _headerName = "HeaderInfo";
        private string _elementName = "ProcType";
        private string _headerNamespace = "http://schemas.tempuri.fi/process/2016/04/";
    
        public ProcessGuidHeader(string attr)
        {
            _attr = attr;
        }
    
        public string Attr
        {
            get { return _attr; }
        } 
    
        public override string Name
        {
            get { return _headerName; }
        }
    
        public override string Namespace
        {
            get { return _headerNamespace; }
        }
    
        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            writer.WriteElementString(_elementName, _attr);
        }
    }
    

    This does not set any namespace for header child element and solves the issue.