A Generic WCF Service for BizTalk

Link. May 19, 2008. Comments [4]. Posted in: BizTalk | WCF

I've been playing lately with a few WCF features as well as with the WCF Adapter in BizTalk Server 2006 R2. As part of that I had a need to set up a receive location using one of the WCF HTTP-based bindings.

Normally, this isn't a big deal; you can easily use the BizTalk WCF Service Publishing Wizard to create the receive location and IIS service application for an orchestration or from a set of BizTalk schemas.

However, this time I did not want to go that way. What I really wanted was just a simple receive location that would simply receive messages and submit them over to BizTalk without tying the receive location to a specific service definition. As far as I could see, the Service Publishing Wizard didn't really have an option for this, but I was confident it could be made to work.

To be honest, I did have a set of schemas I wanted to work with and even a bunch of predefined WSDL files. However, for many reasons (including the sheer complexity of the schemas and WSDL files involved) I didn't want to get that involved in my initial BizTalk message receiver and processor.

Fortunately, turns out that doing what I wanted was fairly easy stuff. In fact, it was so easy that was able to leverage an existing service I had previously created. I basically just copied the .SVC file (and renamed it) alongside the web.config file. I explicitly ignored all the stuff that normally gets generated under the App_Data directory.

I then manually created a matching receive location in BizTalk using the WCF-BasicHTTP adapter, and this worked right away perfectly for my needs!

Just in case you've never looked at what a WCF HTTP receive location generated files look like, it's actually fairly simple stuff. The SVC file contains just a single directive as expected:

<%@ ServiceHost Language="c#" Factory="Microsoft.BizTalk.Adapter.Wcf.Runtime.BasicHttpWebServiceHostFactory, Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>

You can see here that it references the WCF-BasicHTTP adapter. If you wanted to use, say, the WCF-WSHttp Adapter, then you'd use Microsoft.BizTalk.Adapter.Wcf.Runtime.WSHttpWebServiceHostFactory class instead.

The config file is pretty much the default config file generated by the Service Publishing Wizard as well:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
   <configSections>
      <section 
         name="bizTalkSettings" 
         type="Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkConfigurationSection,
            Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0,
            Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
   </configSections>
   <bizTalkSettings>
      <mexServiceHostFactory debug="false">
         <receiveLocationMappings>
            <!--add markupFileName="*.svc"
               receiveLocationName="?"
               publicBaseAddress="protocol://host[:port]" /-->
         </receiveLocationMappings>
      </mexServiceHostFactory>
      <webServiceHostFactory debug="false" />
      <isolatedReceiver disable="false" />
      <btsWsdlExporter disable="false" />
   </bizTalkSettings>
   <appSettings />
   <connectionStrings />
   <system.web>
      <compilation defaultLanguage="c#" debug="false">
         <assemblies>
            <add assembly="mscorlib, version=2.0.0.0, culture=neutral,
               publickeytoken=b77a5c561934e089" />
            <add assembly="Microsoft.BizTalk.Adapter.Wcf.Common, Version=3.0.1.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
            <add assembly="Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
         </assemblies>
      </compilation>
      <authentication mode="Windows" />
   </system.web>
   <system.serviceModel>
      <behaviors>
         <serviceBehaviors>
            <behavior name="ServiceBehaviorConfiguration">
               <serviceDebug 
                  httpHelpPageEnabled="true" 
                  httpsHelpPageEnabled="false" 
                  includeExceptionDetailInFaults="false" />
               <serviceMetadata 
                  httpGetEnabled="false" 
                  httpsGetEnabled="false" />
            </behavior>
         </serviceBehaviors>
      </behaviors>
      <services>
         <service 
            name="Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkServiceInstance" 
            behaviorConfiguration="ServiceBehaviorConfiguration">
            <!--<endpoint
               name="HttpMexEndpoint"
               address="mex"
               binding="mexHttpBinding"
               bindingConfiguration=""
               contract="IMetadataExchange" />-->
            <!--<endpoint
               name="HttpsMexEndpoint"
               address="mex"
               binding="mexHttpsBinding"
               bindingConfiguration=""
               contract="IMetadataExchange" />-->
         </service>
      </services>
   </system.serviceModel>
</configuration>

It's extremely nice to see how the WCF adapter in BizTalk leverages a bunch of my favorite features in WCF to make this a lot simpler (compared to, say, the whole bunch of code that needed to be generated for the original SOAP adapter).

I should mention though, that part of what made it so easy was that my needs were pretty simple: I wanted a simple two-way (request/response) port, and needed no metadata (WSDL) publishing at all (as I said, I already had working WSDL files I could provide to consumers of the service).  Making it one-way wouldn't have been a problem though; as the WCF adapter handles it very gracefully as well.



Wednesday, May 21, 2008 9:52:31 AM (SA Pacific Standard Time, UTC-05:00)
With regards to WSDL, you can expose it by adding and configuring the serviceMetadata section in the BT receive location's Behavior tab and then setting the externalMetadataLocation property. The only minor challenge with that is any changes that you make to your messages (i.e. schemas) need to be reflected in the WSDL. Still, it is a small price to pay for simplicity. :)

We've found that replicating a generic service and exposing a WSDL document is so much more efficient and less frustrating than using the BT WCF publishing wizard.
Joel
Wednesday, May 21, 2008 5:58:20 PM (SA Pacific Standard Time, UTC-05:00)
Joel: Yes, I'm aware of externalMetadataLocation, but totally forgot about it; thanks for bringing it up.

Actually, I don't have to worry in this case about the WSDL and the schemas getting out of sync because both are part of a standard control by a third party. So this is really kind of the scenario where this shines!
Tuesday, June 17, 2008 1:56:08 PM (SA Pacific Standard Time, UTC-05:00)
HI ,

Can you please send me the code for above snippet or any webcast related to the above scenario.

Thanks
reddy
Reddy
Tuesday, June 17, 2008 1:59:00 PM (SA Pacific Standard Time, UTC-05:00)
@reddy: There's really no extra code; those two snippets are really all it takes to enable a WCF receive location for BizTalk. Is there anything specifically you're looking for?
Comments are closed.

About

Tomas Restrepo is a software developer located in Colombia, South America. His interests include .NET, Connected Systems, PowerShell and lately dynamic programming languages. More...

tomasrestrepo @ twitter My Flickr photostream My saved links on delicious My Technorati Profile

email: tomas@winterdom.com
msn: tomasr@passport.com

View my profile on LinkedIn

MVP logo

Syndicate

Ads


Links

Categories

Statistics

Total Posts: 1022
This Year: 92
This Month: 11
This Week: 0
Comments: 791

Blogroll

Post Archive

Other

Copyright © 2002-2008, Tomas Restrepo.

Powered by: newtelligence dasBlog 2.1.8139.823

Sign In