Preserving ASMX web service contracts in WCF
Recently, I had an interesting experience regarding trying to preserve the contents of an ASMX/WSE3 web service contract (using C#, and Xml Serialization attributes) in a WCF service. The mantra of SOAP (and COM/DCOM) is to define a contract as your abstractraction, and then you can swap out implementations w/o affecting the caller.
So here was my interface (.NET 2.0, C#) for the ASMX endpoint:
public interface IFooService
{
[WebMethod]
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
FooResponse Foo(FooRequest request);
}
As you can see here, I asked the ASMX plumbing *not* to wrap my request/response in an additional element since I already had a class defined to be my message contract.
However, when I decided to sprinkle the WCF pixie-dust attributes on my interface:
public interface IFooService
{
[OperationContract] //pixie-dust
[WebMethod]
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
FooResponse Foo(FooRequest request);
}
exposed it in WCF via basicHttpBinding, and pointed my clients talking ASMX I started receiving the dreaded “Contract Mismatch” exception/fault.
After some logging/tracing with WCF Service Trace Viewer and log4net, I found the problem. By default, WCF wraps the soap parameters. In the example above, the ASMX message looked something like this:
<soap:Envelope …(a whole pile of namespaces)>
<soap:Body>
<FooRequest>
<!-- content omitted for brevity -->
</FooRequest>
</soap:Body>
</soap:Envelope>
But the WCF infrastructure was looking for a wrapped parameter (default behavior which I didn’t account for)
<soap:Envelope …(a whole pile of namespaces)>
<soap:Body>
<request>
<FooRequest>
<!-- content omitted for brevity -->
</FooRequest>
</request>
</soap:Body>
</soap:Envelope>
The way to change this default behavior is by creating a MessageContract and setting IsWrapped = false. WCF was treating my data contracts (FooRequest FooResponse).
The takeaway; WCF wraps messages by default, use a tool to trace your SOAP messages to figure out what's on the wire, and it is typically easier to write something new than change something existing :)
jk