Welcome to

Magenic Technologies Community Blog

Sign in | Join | Help

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

Published Monday, June 18, 2007 12:54 AM by jeffk
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
required 
(required)