none
WCF MessageInspector and CreateHeader subnodes RRS feed

  • Question

  • Hey Folks,

    I need to send a soap message with a header like below.  I'm working in WCF 4.5 and am consuming a java web service over which I have no control. 

    <s:Header>
    	<s:Temp>
    		<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    			<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-15846359">
    				<wsse:Username>user</wsse:Username>
    				<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pwd</wsse:Password>
    			</wsse:UsernameToken>
    		</wsse:Security>
    	</s:Temp>
    </s:Header>

    In case you're wondering why the <s:Temp> is there, it's because it was the only way I could find to include the wsse namespace via the CreateHeader method.  Everything inside the Temp tag is a string:

    string headerText = "<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">" + 
          "<wsse:UsernameToken xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:Id=\"UsernameToken-15846359\">" +
          "<wsse:Username>{0}</wsse:Username>" +
          "<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">{1}</wsse:Password>" +
          "</wsse:UsernameToken>" +
          "</wsse:Security>";
    headerText = string.Format(headerText, "user", "pwd");
    MessageHeader myHeader = MessageHeader.CreateHeader("s:Temp", "", headerText, false);

    Unfortunately, this produces the following line inside the Temp tags:

    <s:Temp>&lt;wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;&lt;wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-15846359"&gt;&lt;wsse:Username&gt;user;/wsse:Username&gt;&lt;wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"&gt;pwd&lt;/wsse:Password&gt;&lt;/wsse:UsernameToken&gt;&lt;/wsse:Security&gt;</s:Temp>

    Note all the &lt; and &gt; encoded tag delimiters.  This is unacceptable to be passed to the web service.  If I paste this result into a text file and replace all the &lt; and &gt; with < and > respectively, and paste the result into SoapUI, it works perfectly.

    The key is replacing all the &lt; and &gt;.  How???  I tried escaping the header text, but the parser apparently ignores all attempts to pass < and > as literals, including using <![CDATA[xxx]]>.

    I can think of two approaches, neither one I know how to do.

    1.  After creating myHeader, somehow convert it to a string, replace the delimiters, and write it back to a Message.  Somehow, I think I'll end up with the same thing.

    2.  Instead of including the Security tag as a single string, create subnodes of the Security node.  i.e., create UsernameToken as a subnode of Security, and Username and Password as subnodes of UsernameToken.  The problem there will probably be that all the xmlns prefixes will be removed.  Besides, there doesn't seem to be any built-in method for adding subnodes in the header.

    This seems like such basic functionality that the capability must exist somewhere!  At this point, I'm willing to bet it's impossible. 

    Please, prove me wrong.


    • Edited by LWakeman Friday, March 7, 2014 10:35 PM
    Friday, March 7, 2014 10:32 PM

Answers

  • Hi,

    Note all the &lt; and &gt; encoded tag delimiters.  This is unacceptable to be passed to the web service.  If I paste this result into a text file and replace all the &lt; and &gt; with < and > respectively, and paste the result into SoapUI, it works perfectly

    Then if you do not want to have so many encoded tag delimiters, please use the following:

    string headerText = @"<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">" + 
          @"<wsse:UsernameToken xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:Id=\"UsernameToken-15846359\">" +
          @"<wsse:Username>{0}</wsse:Username>" +
          @"<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">{1}</wsse:Password>" +
         @ "</wsse:UsernameToken>" +
          @"</wsse:Security>";

    Then also check this similar thread:
    How to add attribute to WCF message header with MessageHeader.CreateHeader() method
    http://social.msdn.microsoft.com/Forums/vstudio/en-US/05a561cd-879b-4dc7-ac1a-88a879272400/how-to-add-attribute-to-wcf-message-header-with-messageheadercreateheader-method?forum=wcf .

    Thanks.

    Monday, March 10, 2014 9:24 AM