Custom SOAP Headers: WCF and ASMX

First the good news, WCF clients should just work with ASMX services that use custom SOAP headers.

Now the not so good news, ASMX clients will work with WCF services that use headers, but the object model is pretty funky.  Say you want to do something really crazy like have a header of type string.  The ASMX client will represent that header with a class that looks like this:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="https://www.w3.org/2001/XMLSchema")]
[System.Xml.Serialization.XmlRootAttribute("StringHeader", Namespace="https://xwsinterop/soapwsdl/headers", IsNullable=true)]
public partial class @string : System.Web.Services.Protocols.SoapHeader {
   
    private string[] textField;
   
    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string[] Text {
        get {
            return this.textField;
        }
        set {
            this.textField = value;
        }
    }
}

To use this class, assign a new string array of length 1 to Text and then assign the value of the header to that element and it will work as expected.  These sorts of classes will be generated by ASMX for any simple type, the workaround is to use wrapper classes around the headers on the WCF side.  This will result in a somewhat clunky OM, but it will make sense.

Comments

  • Anonymous
    May 29, 2007
    RESTful Web Services [Via: Jon Udell ] SCSFContrib is Alive! [Via: bsimser ] Expression Studio on MSDN...

  • Anonymous
    June 15, 2007
    Do you have a full example of both a WCF Server demonstrating adding a SOAP header and a ASP.net 2.0/asmx client seeing the header, modifying and sending it back?  I'm not connecting the pieces on what needs to be done on the Server side so it shows up on the client side.  I wan to use basichttpBinding and simply pass a string token back and forth for very basic session management.  We must have a web service client that will run on Windows 2000 Professional, and would very much like to use WCF on the server. I have found WCF Server to WCF Client but not WCF Server to ASP.Net 2.0/asmx client. Any links or code examples would be very much appreciated! Curt

  • Anonymous
    June 18, 2007
    Hi Curt, On the server side the simplest solution is to define a MessageContract that defines the payload and headers for your OperationContract: http://msdn2.microsoft.com/en-us/library/ms730255.aspx Now when you generate the client proxy with wsdl.exe or Add Web Reference, the soap header should be included in it.  To use the header now see this article: http://msdn2.microsoft.com/en-us/library/whew6x7f.aspx If the string header is wrapped in an object in the MessageContract, the object model should be pretty straightforward on the client side.  If it's just a string in the MessageContract it will still work, but you'll have to deal with the object model I describe in this post. Thanks.

  • Anonymous
    June 21, 2007
    Thank you very much for the links and the info. I understand how the message contracts work per the links you mentioned, at least most of it anyway.   What I would like to avoid is rewriting our operation contracts section so that the interface has "message objects" in them instead of our current "object" calls. The 2.0 "WebServices" way of decorating a method with a soap header was like this: [WebMethod] [SoapHeader("myHeaderMemberVariable")] public string MyWebMethod() The main thing I'm trying to accomplish is simply sending a "sessionid" from the .net 2.0 client via a SOAP header to the .net 3.0 WCF server so I can validate the client before making their "MyWebMethod" call. It seems like I'm missing something obvious here.   I tried the "[SoapHeader]" attribute it did not work.   Is there a site somewhere with working examples that use SOAP headers that does Not require the signature of the webmethod to return a MessageContract class? Again, I appreciate the help! Regards, Curt

  • Anonymous
    June 25, 2007
    I don't think there's a complete analog for the SoapHeaderAttribute in WCF. This probably isn't what you'd like but another option would be to use Message Inspectors (http://msdn2.microsoft.com/en-us/library/aa717047.aspx), but now the header won't exposed in the wsdl unless you write some more extension code (http://msdn2.microsoft.com/en-us/library/aa967560.aspx). Thanks.