If you cut your teeth building Web services with ASP.NET, then you've become quite accustomed to the developer productivity that results from the automatic serialization of types to/from the <soap:Body>.  Simply declare your method to accept and return the data type of choice, and the underlying infrastructure automagically takes care of serialization for you.

Unfortunately, all of the examples within the WSE 2.0 documentation show methods declared with the SoapMethodAttribute as taking a SoapEnvelope as an argument and returning a SoapEnvelope as a return value.  If you're at all like me, programmatically creating your SOAP envelopes, along with the <soap:Body>, isn't your idea of developer productivity, and you can't fathom trading all of the power of ASP.NET and it's support of automatic serialization in WebMethods for the supposedly "new and improved" feature set of WSE.

However, while working on my MSMQ transport provider for WSE 2.0, I came across a poorly documented feature of SoapService.  You can declare your SoapMethod to accept and return custom data types, and the WSE infrastructure will take care of serializing those types to/from the <soap:Body>, just like a WebMethod in ASP.NET.  For example, you can derive from SoapService and implement your SoapMethod like:

class MySoapService : SoapService

  [SoapMethod("SomeMethod")] 
  public MyReturnType SomeMethod(MyArgs args) 
 
  }
}

The other side of this equation is equally true.  SoapClient provides two overloads each for SendOneWay and SendRequestResponse.  One of the overloads accepts an object as opposed to a SoapEnvelope, and will automatically serialize the object into the <soap:Body> of the request, thereby providing you an easy way to send custom data types between your SoapClient and the remote SOAP-based service.

class MySoapClient : SoapClient

  public MySoapClient(Uri to) : base(to) 
 
 
  public MyReturnType SomeMethod(MyArgs args) 
 
    return this.SendRequestResponse("SomeMethod", args); 
  }
}

Once again, the beauty of the .NET Framework comes shining through in it's ability to support XML serialization for any and all types, built-in or custom.  You don't have to give this one thought - it just works.

You can also see this demonstrated in some of the WSE 2.0 samples, notably TcpSyncStockService.  Hopefully, this will be more fully documented by release.  Until then, it's called out here in an attempt to make your life a little easier when working with WSE.