What if you like SOAP and don't like web references? - Redux

I started the first post on this, with "this is interesting, sort of" - well judging by the number of people who've asked me for more details on doing it I think I was wrong. Apologies to all, I've been so busy the last few months that I just haven't had time to get some code examples up there...until now!

Get the code here to try this for yourself. Essentially, this is an example of what I discussed before, where you can do dynamic sends using the SOAP adapter. For those that haven't tried it, you might be thinking, what's the big deal, but as I mentioned, theres a couple of gotchas which stop this from working as cleanly as with other adapters.

The first is that you can't just set the OutboundTransportLocation from an orchestration (or receive pipeline) as you would do for other dynamic adapters. This is because the Uri scheme (the bit before the address, e.g. HTTP://) is used by BizTalk to lookup the adapter alias from the adm_AdapterAlias table in the management database. As the SOAP adapter only supports SOAP over HTTP you must set the scheme to SOAP:// in order to route it correctly. But this won't work because then the ASMX proxy plumbing (called by the adapter) will fail as it is expecting HTTP:// and will make the call using SOAP:// instead. The way round this is to set the Microsoft.XLANGs.BaseTypes.Address property of the port - which will deliver the message to the SOAP adapter - and then set the OutboundTransportLocation context property in the Send pipeline. The example code shows how to call a Web service using this technique by pulling the Uri to send the message to from the inbound message itself. This dynamic routing is extremely powerful and very useful for Web services.

The second gotcha is around the use of a proxy. When you add a Web reference to a BizTalk project, similar (but not identical) logic is used to classic ASMX whereby a proxy is generated from the URL you provide in the wizard. The proxy contains the Web methods that map to the operations on the provider's WSDL. The problem is that you end up baking the service interface into the client. Rather than creating a client proxy for each client (which is a pain), what we really want is a generic proxy capable of calling any client. Worse than this, ASMX forces the SOAPAction HTTP header (for SOAP 1.1 support) to match the name of this method which makes it very inflexible. Changing this however turns out to be pretty easy using reflection. The code in the download overrides the Invoke method of the SoapHttpClientProtocol in the System.Web.Services.Protocols namespace. Normally this method is called by the Webmethod passing the name of the Webmethod itself (which is Dispatch in the sample). Invoke itself then uses reflection to get the method parameters etc to formulate the call to the service implementation. To keep things simple the code here only deals with a single parameter, XmlNode. Of course you could easily extend this if you wanted to but then you'd be wanting to pass multiple Xml docs which kinda goes against the philosophy of doc/lit. The orch's Send port is then configured to use our generic proxy and call the Dispatch method to make this all work.

There are three projects in the solution, BizTalk (with the Send pipeline and Orch), the generic proxy called by the SOAP send adapter and a simple Web service implementation to call. Simply compile everything, deploy the BizTalk project and GAC the generic proxy assembly. Deploying will create all the ports (sorry about the names) - just create a folder c:\webrefsfilein and enlist and start the orch. You can then drop in the xml file in the Test Data folder in the BizTalk project. There is tracing code throughout, so grab the invaluable sysinternals (sorry, Microsoft) tool, Debug Viewer here. Run the solution (with the Web service as the default startup). When you drop the file in it should call the Web service (specified in the file) and return a result, logging the call (see pic below). Enjoy!


Posted Jun 07 2007, 02:00 PM by jon-fancey

Comments

Christopher Steen wrote Link Listing - June 10, 2007
on 06-10-2007 7:19 PM
Give it a REST! [Via: Anil John ] GWT a Year Later: Was it the correct level of abstraction? [Via: Dietrich...
Iztok Koban wrote re: What if you like SOAP and don't like web references? - Redux
on 07-04-2007 3:34 AM
Hello,

I am trying out your solution and got a 'NullReferenceException: Object reference not set to an instance of an object' because the methode SoapHttpClientProtocol.ReadResponse in the ServiceProxy returns a one object array which is null. Any idea ?

Thanks for your support!
Amit Rohilla wrote re: What if you like SOAP and don't like web references? - Redux
on 07-17-2007 9:35 PM
Is this type of Dynamic Routing possible with BizTalk R2 with WCF adapters
I am getting the following error when I am usiing WCF-WSHttp instead of SOAP
"
The Messaging Engine could not send the message to the dynamic send port. The outbound transport could not be resolved because a matching transport protocol prefix could not be derived from the URL "WCF-WSHttp://localhost:1343/DynamicWCFservice.WCF/Service.svc"
Michael wrote re: What if you like SOAP and don't like web references? - Redux
on 07-30-2007 10:34 AM
Does this work with XML-RPC?
Ravikanth wrote re: What if you like SOAP and don't like web references? - Redux
on 08-05-2007 8:46 PM
First of all I would like to thank Jon Fancey for the wonderful work that he has done. I have applied your idea in the send pipeline to change the scheme back to http:// and it works. Once again thank you Jon.
Doug wrote re: What if you like SOAP and don't like web references? - Redux
on 08-08-2007 11:07 AM
have you tried the override BTS.OutboundTransportType = "SOAP"? this is the type override according to the BTS help.
I haven't got either to work, but that may be unrelated. Thanks for your work.
Doug
Vadim wrote re: What if you like SOAP and don't like web references? - Redux
on 11-05-2007 1:28 AM
I have the same problem like Iztok Koban:

I am trying out your solution and got a 'NullReferenceException: Object reference not set to an instance of an object' because the methode SoapHttpClientProtocol.ReadResponse in the ServiceProxy returns a one object array which is null. Any idea ?
Scott wrote re: What if you like SOAP and don't like web references? - Redux
on 11-27-2007 6:49 AM
If you step through your code you will see that the solution does indeed call the underlying web service.

I think the NullReferenceException happens becasue the ServiceProxy thinks the web service call is one way; therefore, it always returns null.

The only hurdle to getting this working is to somehow get the ServiceProxy to make the call request response instead of one way.

I have no clue how to do that - I checked and tried all kinds of things and always get the same result.

Mark Coleman wrote re: What if you like SOAP and don't like web references? - Redux
on 02-18-2008 7:19 AM
Hi Jon,
Thanks for a great post. I finally managed to get a dynamic send to a SOAP web service working. For what it's worth here are my findings:

1) I created a simple web service and then generated a proxy class using wsdl.exe. I then added the proxy to its own project and built this as a strong named assembly, deployed to the GAC.

2) I didn't need to use a soap:// prefix on the URI. Simply setting the Microsoft.XLANGs.BaseTypes.TransportType property on the send port to "SOAP" did the job of directing the request to the SOAP adapter.

3) The request would fail if I did not populate the SOAP.TypeName property. This should be set to the Namespace.Class of the proxy.

4) The SOAP.AssemblyName property should be set to the Namespace.Class, Assembly, Version, Culture, PublicKeyToken. e.g.
msgSendRequest(SOAP.AssemblyName) = "BtsTest.CalcWebServiceProxy.CalcService,CalcWebServiceProxy, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b713f1108bae3109";

5) The Operation on the dynamic Send Port needs to use the same name as the WebMethod being called.

6) The method signature of the WebMethod should be public XmlNode MyMethod(XmlNode Message)

Hope this helps.
Mark Coleman wrote re: What if you like SOAP and don't like web references? - Redux
on 02-20-2008 2:45 PM
I have put the steps that worked for me more formally on my blog at http://biztalk-dev.blogspot.com/2008/02/dynamic-soap-adapters.html

Cheers

Add a Comment

(required)  
(optional)
(required)  
Remember Me?