Consuming WCF services without orchestration
There are plenty of scenarios where orchestration is an unnecessary addition to service bus processing. Recall that an orchestration's prime benefit is the injection of a stateful, sequential series of steps to message processing. If the "processing" of a message can consist solely of the core BizTalk messaging components (receive ports, send ports, pipelines, maps, and subscriptions), then a messaging-only solution is the way to go. A general rule among BizTalk architects is that you avoid orchestration and concentrate on pure messaging when at all possible. This isn't because orchestration is intrinsically bad but rather because many situations actually don't require the overhead and complexity of a workflow.
That said, how nicely does the BizTalk bus play with WCF services when no orchestration is involved? Quite well, thank you. Let's look at how we may route inbound data to a WCF subscriber using only the message bus.
In our new scenario, we have a target service in our enterprise resource planning (ERP) system that accepts new order notices and uses WCF's WsHttpBinding. We'd like to call this service whenever a new product order enters the MessageBox
. This subscriber does not need any direct knowledge of the upstream publisher or how the message arrived to the bus.
- We start this example by referencing the target service from within Visual Studio. This is done by once again right-clicking the BizTalk project and choosing Add and then Add Generated Items.
- The Consume WCF Service is selected, and when the BizTalk WCF Service Consuming wizard launches, the Metadata Exchange Endpoint is picked as the source of the service metadata.
- Now we plug in the valid HTTP endpoint URI of our WCF service:
When the wizard completes, we have a set of metadata files (schemas, bindings, and orchestrations) that help describe the service and how to consume it. This example doesn't use orchestration, but we do still require one hand-built BizTalk artifact—a map. The WCF service expects the order data to be in a particular format, so we should design a map that gets applied by the outbound send port. The BizTalk map takes the repeating set of order items and puts them into their appropriate fields in the target schema.

Now we build and deploy our updated project. Once that deployment has succeeded, we import the binding generated by the BizTalk WCF Service Consuming wizard. For this scenario:
- Let's import the custom binding (
OrderService_Custom.BindingInfo.xml
) so that we can see the different properties this adapter exposes. - A send port is created for the WCF-Custom adapter, but note that the binding specified by the adapter matches that of our service endpoint,
wsHttpBinding
.
On the General tab of the adapter configuration, observe that there is a section called SOAP action header. This contains the SOAP action that will be attached to the outbound messages for this send port.

The BtsActionMapping
wrapper in this textbox is used to support multiple SOAPAction
values. However, this also means that something needs to set the BTS.Operation
value, which the WCF adapter uses to choose the appropriate SOAP action from this collection. Typically, this is set by the orchestration's logical send port operation name, but in the absence of an orchestration, we would have to set the BTS.Operation
value in a custom pipeline component. Before throwing up your hands and swearing loudly at this unnecessary complexity, breathe deeply and relax. Luckily, this textbox also supports an alternate format that is more supportive of simple content-based routing scenarios. A single SOAP action URI in this textbox is used when you want to apply the same SOAPAction
header to all messages transmitted by the send port. For our scenario, let's switch this to the single SOAPAction
header that corresponds to our target service operation.

Next, we must apply our XSLT map to this send port. The map is a required component because our service is expecting a very specific data format that does not match the original structure of the data.

Our final step is to introduce a valid subscription for this send port. Without one, this port will never receive any messages published to the bus. Because we'd like to pull every order from the MessageBox
, our subscription should be type-based, not context-based. A context-based subscription would say that we are subscribing to properties of the message (for example, which port it arrived at) instead of anything relating to the message itself. We want to subscribe to all messages of a particular type. The subscription applied can be seen in the following screenshot:

Now, technically we are finished. If we send a message into BizTalk, it should route to a listening send port and produce the expected tracing statements. However, see the following Pitfall to resolve an error with our current configuration.
Note
Pitfall
The solution, as it stands now, will raise an exception. Why? The WCF service that BizTalk calls does not return a response message. However, the auto-generated BizTalk binding file was for a two-way send port. So, when the WCF service is called, the request is successful but we end up with a subscription not found exception on the (empty) response message. We can fix this by creating a new one-way send port with configuration settings (adapter type, URI, binding, SOAPAction
, and subscription) identical to those of the auto-generated port.
- Flask Web全棧開(kāi)發(fā)實(shí)戰(zhàn)
- LaTeX Cookbook
- 潮流:UI設(shè)計(jì)必修課
- The React Workshop
- Hands-On JavaScript High Performance
- Getting Started with Gulp
- Python從入門(mén)到精通
- Buildbox 2.x Game Development
- Mastering Adobe Captivate 7
- 零基礎(chǔ)看圖學(xué)ScratchJr:少兒趣味編程(全彩大字版)
- Python高性能編程(第2版)
- 分布式系統(tǒng)架構(gòu)與開(kāi)發(fā):技術(shù)原理與面試題解析
- Programming MapReduce with Scalding
- Learning Adobe Muse
- 移動(dòng)應(yīng)用界面設(shè)計(jì)