BizTalk Server and WCF Integration

Atul Gupta (Infosys Technologies Ltd)
Amit Praful Shah (Infosys Technologies Ltd)
Jitendra Pal Thethi (Infosys Technologies Limited)

September 17, 2007

Summary

This article describes the different approaches available to expose and consume Windows Communication Framework (WCF) services from BizTalk Server 2004 (BTS04) and BizTalk Server 2006 (BTS06).

Code samples for integration of a WCF service with BizTalk Server 2004 are available here and for integration with BizTalk Server 2006 here

Contents
  • Introduction
  • Overview of WCF and BizTalk Server technologies
    • WCF
    • BizTalk Server
  • WCF Service Used as Reference
  • Accessing WCF Services from BizTalk Server
  • Exposing BizTalk Server Orchestrations as WCF Services
  • Issues and Troubleshooting
  • Conclusion
Introduction

With the November 2006 release of .NET Framework 3.0, the wait is finally over for software professionals. The core components of this managed code programming model – Windows Presentation Foundation (WPF), Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) – has revolutionized the way software is programmed.

This article focuses on the different options available for communication between WCF and BTS06. While much of the discussion will also be applicable to BTS04, any discrepancies in implementation for BTS04 will be highlighted.

There is a WCF Adapter for BTS06 is available on the CodePlex Web site. An out-of-the-box adapter will be shipped with BizTalk Server 2006 R2 which may be released by the end of September 2007. An overview of the R2 WCF Adapter's capabilities is available at the following blog post. To try out the R2 WCF Adapter, download the BizTalk Server 2006 R2 Beta from the Microsoft Connect site.

However, you may need to integrate existing BizTalk-based applications with WCF to do the same. In this article we present various options to achieve interoperability in cases where upgrading to BizTalk Server 2006 R2 is not possible. The article merely outlines the approaches and does not deal with them in an exhaustive manner. Nor does it provide a benchmark to compare the approaches. You need to evaluate and choose one among the suggested techniques after taking into account the needs of your application.

Note: If you are upgrading to BizTalk 2006 R2, then working with WCF Adapter will be ideal due to the ease of use, deployment and management it offers.

Overview of WCF and BTS06 Technologies

Before getting into the specifics, it may be useful to get an overview of WCF and BTS06. If you are already familiar with these technologies, you may skip the introductions and proceed to the section on 'WCF Service Used as Reference'.

Windows Communication Foundation

WCF is Microsoft's unified platform used for rapidly building secure, reliable and interoperable distributed applications. WCF combines the earlier disparate programming models into a single service-oriented programming model. In the world before WCF, software developers had to pick from numerous technology choices in order to create and expose services that could be consumed in a distributed environment. While developers chose web services for interoperability and Microsoft Message Queuing (MSMQ) for reliable messaging, they used Enterprise Services for transaction management, .NET Remoting for high performance systems and Web Service Enhancements (WSE) for secure messaging, resulting in the same logic being duplicated when the component had to be exposed over multiple channels.

At a high level, every WCF service consists of the following three parts:

  1. The Service Contract that defines 'what' the service does and a service class that contains the implementation for the service.
  2. Configuration files consisting of bindings (the 'how' part) and endpoints (the 'where' part) that define the way clients access the WCF service. These configuration files are independent of implementation. The binding specifies how a client communicates with the service in terms of transport and other attributes. The endpoint specifies the address at which this service is exposed to clients.
  3. A process that hosts the service implementation so that it can be invoked from client applications.

The following diagram depicts a WCF service being invoked by a client:

 

Bb973215.Biztalk_wcf_wcf-communication(en-us,MSDN.10).jpg

Figure 1: WCF Communication

 

Given below, are a sequence of steps that need to be followed for implementing and making a WCF service available for consumption.

Defining the Contract

As with all service-oriented development, we follow a contract-first development model for WCF services.

Two types of contracts need to be specified:

  1. Service contract: This contract defines the interface of the service, which is the set of operations that are implemented and exposed by the service. The service contract uses a specific attribute viz [OperationContract]to define the operations. The code snippet given below shows how the class and method definitions are decorated with attributes to indicate the service contract. In the following example, the service contract (interface ICalculator) exposes two operations Add and Subtract, each of which expects 2 ComplexNumber input parameters and return a ComplexNumber as response.

  2. [ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        ComplexNumber Add(ComplexNumber n1, ComplexNumber n2);
        [OperationContract]
        ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2);
    }
    
  3. Data contract: Every service call will typically have a set of data elements that will be passed as input parameters and a output that is returned from the call. The data contract helps in formalizing this data exchange. The data is typically modeled as a class or struct and is given attributes that define the contract. The data contract controls the way the request object, which is passed as a parameter to the service call, is serialized and hence controls the SOAP (Simple Object Access Protocol) message format that flows on the wire.

An example of a data contract is given below. Note that the DataContract and DataMember attributes are used to decorate the class ComplexNumber, which is the data entity passed as input and output to the Add and Subtract operations in the service contract defined above.


   [DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]
   public class ComplexNumber
   {
       [DataMember]
   public double Real;
       [DataMember]
       public double Imaginary;
   }

Implementing the Contract

Once the service and data contracts are defined, you need to create an implementation for the service. This is done by first defining the class that will implement the interface in the service contract. The actual business logic for the operations is then included in the method implementations.


public class CalculatorService : ICalculator
{
    public ComplexNumber Add(ComplexNumber n1, ComplexNumber n2)
    {
        return new ComplexNumber(n1.Real + n2.Real, n1.Imaginary + n2.Imaginary);
    }
    
    public ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2)
    {
        return new ComplexNumber(n1.Real - n2.Real, n1.Imaginary - n2.Imaginary);
    }
}

Configuring End Points

As mentioned earlier, the service is implemented independent of the transport or address over which the service is eventually exposed. This is possible because in WCF, the transport and address details are specified as attributes in external configuration files.

To configure end points exposed by WCF services, it is mandatory to define the following details for each endpoint:

  • Contract: The contract is the interface or the service contract that the service implements. In the sample shown below, the endpoint is configured to expose the ICalculator service contract.
  • Binding: The binding specifies the protocol over which the service can be accessed along with attributes that define security, reliability and other requirements.
  • Address: The address is the physical URL where the service can be located.

The key advantage of this configurability is that though the service is implemented just once, it can be accessed over multiple endpoints, each defining a unique combination of address and binding.

A sample configuration for end points is as follows:


<system.serviceModel>
  <services>
    <service
      name="Microsoft.ServiceModel.Samples.CalculatorService"
      behaviorConfiguration="CalculatorServiceBehavior">
      <endpoint
        address=""
        binding="wsHttpBinding"
        contract="Microsoft.ServiceModel.Samples.ICalculator" />
      </service>
    </services>
    
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

 

Hosting the WCF Service

The final step is to host the service in a process. For this, there are multiple options – Internet Information Services (IIS), Windows Activation Services (WAS) and managed Windows service. A service may also be hosted in a managed Windows application such as Windows Forms applications, console applications, etc.

The following links provide more details about.NET Framework 3.0 and WCF:

BizTalk Server 2006

BizTalk Server is an integration product from Microsoft that enables enterprises to automate, deploy and monitor business processes. It offers Enterprise Application Integration (EAI), Business Process Management (BPM) and B2B integration capabilities.

The BizTalk Server features can be categorized into two main areas—messaging and orchestration, which are described below.

  • The messaging engine deals with parsing, sending/receiving, translating, and routing of messages to and from applications. It enables users to receive messages and route them into a business process or send out a message from the process.
  • The orchestration engine deals with modeling and executing processes, and provides a tool to design and implement business processes. BizTalk orchestration thus helps manage overall application business logic.

Messaging and orchestration are used together; with messaging providing the receipt and delivery capabilities that orchestration rely on.

The diagram below shows the important components of BizTalk server:

BTS06

Figure 2: BizTalk Server Architecture

 

Other important BizTalk server components include:

  1. Business Rules Engine (BRE): The BRE allows one to create a set of business rules as policies and evaluate data based on these rules. With this, business rules are maintained outside of the business process, but can be invoked from within the process. This makes the systems easier to configure and maintain.
  2. Business Activity Monitoring (BAM): The BAM component makes it possible for the extraction of relevant information from business processes as they are executing and hence to monitor the processes in real time.
  3. Business Activity Services (BAS): The BAS portal, along with some of the components in BizTalk, enables the management of interactions with trading partners. It also helps integrate an enterprise's business processes with those of the partners.

 

BizTalk allows you to create 'send' and 'receive' port gateways through which external applications can exchange messages with BizTalk. The ports can be configured to use a set of transport protocols and application adapters that are shipped with BizTalk Server. With these adapters, BizTalk can exchange messages over multiple channels such as files, MSMQ, HTTP (Hypertext Transfer Protocol), SOAP, IBM MQ, etc. Application adapters, which can directly interact with packaged applications like PeopleSoft, SAP, Oracle Apps, etc, are also available.

Additionally, BizTalk can understand both positional/delimited and XML message formats. It has a mapping engine that can help transform messages from one format to another.

The flow of a message through BizTalk is shown in the diagram below:

BTS Msg Flow

Figure 3: Message flow in BizTalk Server

 

Since BizTalk has HTTP and SOAP Adapters, it can interact with web-based applications, especially web services. The BizTalk Server interacts with services in the following two ways:

  1. BizTalk process orchestrations can be exposed as Web services. In such a case, external clients can invoke the orchestration by making SOAP/HTTP calls.
  2. BizTalk can consume Web services by using the SOAP Adapter.

More information on BizTalk Server 2006 is available at the following URLs:

The WCF Service Used as Reference

This article uses the following WCF service to explain BizTalk-WCF integration options:


[ServiceContract()]
public interface IWCFService
{
   [OperationContract]
   int GetStockInfo(int prodID);
}

public class WCFService : IWCFService
{
   public int GetStockInfo(int prodID)
   {
      // Get the current inventory level for the Product ID from the
      // database
   }
}

In the above service, a Product ID is the input parameter expected by the GetStockInfo() method. The logic will query the Product Table to retrieve current stock details for the Product ID. The return value is an integer indicating the current stock available.

 

BizTalk – WCF Integration

Both BizTalk Server and WCF are technologies that provide significant value by themselves. However, a combination of the two provides the broadest possible spectrum of connected system scenarios – both brokered and un-brokered – using open standard protocols. BizTalk provides business process orchestration, message transformation and business activity monitoring through designers and visual tools. WCF provides a unified framework for building secure, reliable and transacted web services. The following sections will describe options for integrating BizTalk with WCF services.

  1. Consuming a WCF Services from BizTalk:
    1. Use the WCF Adapter. Currently in CTP, it will be released with BizTalk 2006 R2.
    2. WCF service exposed over basicHttpBinding and consumed from orchestration.
    3. WCF service exposed on wsHttpBinding endpoint. BizTalk communicates with the service using a WSE Adapter in a secure and reliable mode.
    4. WCF Service endpoint on msmqIntegrationBinding. BizTalk consumes the service using an MSMQ Adapter.
    5. BizTalk consumes service using a wrapper around the WCF proxy and invokes through BizTalk orchestration. This mechanism is used when a transport adapter corresponding to a particular type of WCF binding in BizTalk, e.g. netTCPBinding, is not available in BizTalk.
  2. Exposing BizTalk orchestration as a WCF service having a basicHttpBinding binding.

The following table shows the options for communication between BizTalk Server and a WCF service for various system-provided WCF bindings. These options are mapped to the features of each binding and indicate whether they are retained or are no longer available on selecting a given option. Use the following table to select the option that satisfies all features required in your scenario:

Options for Communication
with BizTalk

Features of Bindings

Transport Level Security

Message Level Security

Session Support

Transactions  Support

Correlation and Duplex Channel

BasicHttpBinding

P

V

V

V

V

1

Orchestration using Send shapes bound to endpoint on HTTP Adapter

P

V

V

V

V

2

Wrap WCF Proxy as a .NET assembly

P

V

V

V

V

WsHttpBinding

P

P

P

P

V

1

Orchestration using Send Shapes bound to endpoint on  WSE Adapter

P

P

V

V

V

2

Wrap WCF Proxy as a .NET assembly

P

V

V

V

V

WsDualHttpBinding

P

P

P

P

P

1

Orchestration using Send shapes bound to endpoint on  WSE Adapter

P

P

V

V

V

2

Wrap WCF proxy as a .NET assembly

P

V

V

V

V

NetTcpBinding

P

P

P

P

P

1

Wrap service in a .NET proxy assembly.

V

P

V

V

V

NetNamedPipesBinding

P

P

P

P

P

1

Wrap Service in a .NET proxy assembly.

V

P

V

V

V

NetMsmqBinding

P

P

X

P

X

1

As MSMQ endpoint. Requires additional transformation

P

V

V

P

V

2

Wrap service in a .NET proxy assembly.

V

P

V

V

V

MsmqIntegrationBinding

P

V

V

V

V

1

As MSMQ endpoint. Requires additional transformation

P

V

V

V

V

2

Wrap service in a .NET proxy assembly.

V

V

V

V

V

NetPeerTcpBinding

P

P

V

V

P

1

Wrap service in a .NET proxy assembly.

V

P

V

V

V

Table 1: Options for BizTalk – WCF integration

 

The following business case sample may help you understand the working of BizTalk and WCF:

  1. A user receives an invoice from a file receive location using the File Adapter.
  2. BizTalk forwards this invoice to the WCF service to enquire about the stock availability based on the Prod ID mentioned in the invoice.
  3. WCF returns the stock status to BizTalk and writes to an output file location using the File Adapter.
Accessing WCF Services from BizTalk Server
WCF Service with BasicHttpBinding binding, consumed from BizTalk

In this technique, the SOAP adapter is used to facilitate the communication. BizTalk consumes the WCF service by making a web reference to the WCF service exposed over basicHttpBinding. The basicProfileBinding conforms to WS-I Basic Profile 1.0 standards. The SOAP Send Adapter can be used to interface with such an endpoint.

In order to consume a service that uses BasicHttpBinding:

  1. Add a web reference to the WSDL at endpoint address.
  2. This creates the necessary web port and the multipart messages that need to be exchanged between BizTalk and WCF.
  3. Transform source messages to request schema messages. Such messages can be sent from orchestrations.

The following is the detailed sequence of steps to be followed for consuming a WCF service exposed over the BasicHttpBinding:

  1. Create a new web site using the WCF service template as shown below:

  2. WCFService

  3. Figure 4: Creating a new WCF Service project

  4.  

  5. Define the service contract and the implementation as shown earlier. However, modify the bindings to use basicHttpBinding as the WCF service template creates wsHttpBinding by default. Also set the byPassProxyOnLocal=true for the basicHttpBinding configurations in the web.config file that is created.

  6. An important snippet of the web.config file for basicHttpBinding is as follows:

  7. 
    <services>
        <service name="WCFService"
    behaviorConfiguration="returnFaults">
        <endpoint contract="IWCFService"
    binding="basicHttpBinding"/>
    </service>
    
    <serviceMetadata httpGetEnabled="true"/>
    
    <basicHttpBinding>
      <binding name="Binding1" bypassProxyOnLocal="true">
      <security mode="None"/>
      </binding>
    </basicHttpBinding>
    
    
  8.  

  9. It defines the service contract of the WCF service and the binding information for basicHttpBinding. Refer to the MSDN site for more information on basicHttpBinding.

  10. Publish the WCF service onto a local IIS.

  11. Create a new BizTalk project that will consume the WCF service set up using basicHttpBinding.

  12. From the BizTalk project, add a web reference to the WCF service. This creates the web port and the request-response message that BizTalk uses to consume the WCF service. This is shown in the figures below:

  13.  

  14. WebRefFile

  15. Figure 5: Adding a web reference to the WCF service

  16.  

  17. The web port type and multipart messages are automatically created after addition of the web reference as seen in the orchestration view. Logical ports can now be added to the orchestration design surface. The WCF service can be invoked from the orchestration by passing the request message type to the port and subsequently receiving the response.

  18. Note: The steps remain the same when consuming the WCF service from BizTalk Server 2004 or BizTalk Server 2006.

WCF Service Exposed on WsHttpBinding Endpoint

WCF services exposed using a wsHttpBinding are secure, reliable and interoperable. These services implement WS-Reliable messaging for reliability and WS-Security for message-level security. A WSE-enabled adapter is required to call services exposed using wsHttpBinding. Microsoft has released a BTS04-compatible WSE 2.0 Adapter which can be used for communication. However, currently, there is no BTS06-compatible adapter for WSE 3.0 available from Microsoft. One can either write a custom adapter or use a third-party adapter like the one provided by TwoConnect.

Microsoft WSE 2.0 Adapter

The WSE 2.0 Adapter, available for BTS04, can be used for interfacing. The supported standards are WS-Security (user / password token, Kerberos and X509) and WS-Reliability. More details are available on the MSDN web site.

BizTalk WSE 2.0 adapter Product Information.
The WSE 2.0 adapter can be downloaded from here and the SP1 is available here.
A detailed walk through on using the WSE 2.0 adapter is available in this TechNet article.

WSE 3.0 Adapter from TwoConnect

TwoConnect has published a WSE 3.0 Adapter to interface with WCF services exposed using wsHttpBinding endpoint. You can find more details on the adapter at http://adapterworx.com/cs/products/wse3.0.aspx.

For connecting to WCF using the WSE 3.0 Adapter from TwoConnect, follow the steps given below:

  1. Create and publish a WCF service according to the steps listed in the basicHttpBinding section. An important snippet from the web.config file is as follows:

  2.      <services>
             <service name="WCFService" behaviorConfiguration="returnFaults">
                 <endpoint contract="IWCFService" binding="wsHttpBinding"/>
             </service>
         </services>
    
             <serviceBehaviors>
                 <behavior name="returnFaults" >
                     <serviceDebug includeExceptionDetailInFaults="true" />
                     <serviceMetadata httpGetEnabled="true"/>
                 </behavior>
         </serviceBehaviors>
    
  3.  

  4. Create a new BizTalk project. Run the WSE 3.0 Adapter Wizard against the WCF service URL. This helps create the necessary schemas and port types required to interact with the WCF service. To run the WSE 3.0 Adapter, do the following:

    • Right click BizTalk project and select Add Generated Items > WSE Adapter.
    • Specify the wsdl to the WCF service created.
    • Select the service contract BizTalk uses to interact with the WCF service as shown in the figures below:
  5. Adap1

  6. Figure 6: Referencing WSDL URL information in the Schema Generation Wizard

  7.  

  8. adap2

  9. Figure 7: Specifying the web methods in the Schema Generation Wizard

  10.  

  11. Assign appropriate message types to the multipart messages created by the WSE 3.0 Adapter Wizard. Also create a port type based on the one added by the wizard. You can consume the WCF service from an orchestration using the ports created above.

 

WCF Service Endpoint on MsmqIntegrationBinding

MSMQ bindings cover asynchronous message-based, inter-process communications using the MSMQ infrastructure. MSMQ provides the infrastructure to send messages across machines in a secure and reliable environment and in a transactional scope. This messaging pattern helps build scalable applications as the number of blocked and wait threads is minimal.

The sample described in this section, works as follows:

  1. BizTalk receives an invoice.
  2. It submits the message using an MSMQ Adapter to the private MSMQ queue present on a remote system where the WCF service is hosted.
  3. The WCF service picks up the message from the MSMQ queue, finds out the stock status, updates the message, and posts it back to the same queue.
  4. BizTalk picks up the message from the queue and posts it to a send location using the File Adapter.
  5. The WCF service is hosted inside a console application.

Steps

  1. Define the service contract as shown below:

  2. [ServiceContract(Namespace = "http://Infosys.BiztTalkWCF.Samples")]
    [ServiceKnownType(typeof(InvoiceType))]
    public interface IOrderProcessor
    {
        // Specify One Way OperationContract set to true so MSMQ will not 
        // wait for a return value from the WCF service, and not 
        // correlated reply message is returned back by the WCF service.
        [OperationContract(IsOneWay = true, Action = "*")]
        void SubmitInvoice(MsmqMessage<InvoiceType> msg);
    }
    
  3. Note the use of the ServiceKnownType attribute. This helps expose .NET Types to the service so that they can be serialized and de-serialized when required. InvoiceType is a class with fields having one-to-one mapping. The source schema elements are present in the BizTalk message.

  4. Also note that since the message is passed to the WCF service over MSMQ, the parameter type of SubmitInvoice OperationContract will be of type MsmqMessage.

  5. Define the class for ServiceKnownType i.e. InvoiceType. The class definition for InvoiceType is given below:

  6. 
    [Serializable]
    public class InvoiceType
    {
       public string InvNo;
       public DateTime InvDate;
       public int ProdID;
       public int Qty;
       public int Price;
       public int StockAvail;
       public string Remarks;
    }
    
  7.  

  8. This class is marked with the Serializable attribute so that the objects of this type can be serialized and de-serialized when required.

  9. The service receives an input message from MSMQ and posts a response. Code for the WCF service is given below and is hosted inside a console application:

  10. public class OrderProcessorService : IOrderProcessor
    {
    //We have used a Transactional Queue hence done these settings
    //for the OperationBehavior attribute
    [OperationBehavior(TransactionScopeRequired = true,
    TransactionAutoComplete = true)]
    public void SubmitInvoice(MsmqMessage<InvoiceType> ordermsg)
    {
        InvoiceType invoice = (InvoiceType)ordermsg.Body;
        int prodID = (Int32)invoice.ProdID;
        SqlConnection con = new SqlConnection("Data
        Source=localhost;Initial Catalog=Northwind;Integrated 
        Security=SSPI")
        SqlCommand command = new SqlCommand("SELECT * FROM Product WHERE Product.ProductID= prodID");
        command.Connection = con;
        con.Open();
        SqlDataReader dr = command.ExecuteReader();
        int val = 0;
        while (dr.Read())
        {
            //Find matching product ID supplied with the Product ID in
            //the Product Table.
            if (prodID == ((int)dr.GetValue(0)))
            {
                //Check the Stock with the ReOrder Level
                if (((int)dr.GetValue(2)) >= ((int)dr.GetValue(3)))
                {
                    val = dr.GetInt32(2);
                }
            }
        }
        dr.Close();
        con.Close();
        invoice.StockAvail = val;
        ordermsg.Body = invoice;
        SendResponse(ordermsg);
    }
    
    private void SendResponse(MsmqMessage<InvoiceType> msgtomsmq)
    {
        OrderResponseClient client = new
        OrderResponseClient("OrderClient");
        MsmqMessage<InvoiceType> msmqmsg = new
        MsmqMessage<InvoiceType>(msgtomsmq.Body);
    
        client.GetStockInfo(msmqmsg);
        client.Close();
    }
    
    //Host the WCF service within this EXE console application.
    public static void Main()
    {
        string queueName = 
        ConfigurationManager.AppSettings["orderQueueName"];
        if (!MessageQueue.Exists(queueName))
            MessageQueue.Create(queueName, true);
    
        // Create a ServiceHost
        using (ServiceHost serviceHost = new 
        ServiceHost(typeof(OrderProcessorService)))
        {
            serviceHost.Open();
            Console.WriteLine("The service is ready.");
            Console.WriteLine("Press <ENTER> to terminate service.");
            Console.ReadLine();
        }
    }
    }
    
  11. Implement the interface and logic for sending the message from the WCF service to MSMQ as shown below. Note that this custom client has to be created since there is no implicit service contract between WCF and MSMQ.

  12. [ServiceContractAttribute(Namespace=
    "http://Infosys.BizTalkWCF.Samples")]
    public interface IOrderProcessorResponse
    {
        [OperationContractAttribute(IsOneWay = true, Action = "*")]
        void GetStockInfo(MsmqMessage<InvoiceType> msg);
    }
    [GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute()]
    public partial class OrderResponseClient:
    ClientBase<IOrderProcessorResponse>,IOrderProcessorResponse
    {
        public OrderResponseClient(){ }
    
        public OrderResponseClient(string configurationName)
        : base(configurationName){ }
    
        public OrderResponseClient(System.ServiceModel.Channels.Binding
        binding, System.ServiceModel.EndpointAddress address)
        : base(binding, address) { }
    
        public void GetStockInfo (MsmqMessage<InvoiceType> msg)
        {
            base.Channel.GetStockInfo(msg);
        }
    }
    
  13. The following are the important sections of the app.config file for msmqIntegrationbinding:

    1. Define an attribute in the appSettings for configuring the Queue name.

    2. <appSettings>
          <!-- use appSetting to configure MSMQ queue name -->
          <add key="orderQueueName" value=".\private$\myqueue" />
      </appSettings>
      
    3. The service definition for exposing an endpoint that uses msmqIntegrationBinding is as follows:

    4. <service name="OrderProcessorService">
          <endpoint address="msmq.formatname:DIRECT=OS:.\private$\myqueue"
                                  binding="msmqIntegrationBinding"
          bindingConfiguration="OrderProcessorBinding"
                                  contract="IOrderProcessor">
          </endpoint>
      </service>
      
    5. On the client-side, the following client endpoint definition is required to consume the service:

  14. <client>
        <endpoint name="OrderClient"
    
                address="msmq.formatname:DIRECT=OS:.\private$\myqueue"
                            binding="msmqIntegrationBinding"
    
                bindingConfiguration="OrderProcessorBinding"\
                            contract="IOrderProcessorResponse">
        </endpoint>
    </client>
    
  15. Create a private transactional queue named ”myqueue” using the MSMQ manager

  16. Create the Biztalk orchestration which will post and receive the message to and from MSMQ.

Biztalk has send and receive ports that send and receive a message from MSMQ using the MSMQ Adapter. The port binding is set to the "specify later" option. After deployment, set the properties of the send and receive ports for MSMQ bindings from the BizTalk Explorer as follows:

SendMSMQ

Figure 8: Configuring the MSMQ Send Adapter

 

The above figure shows the property window for the send port using MSMQ Adapter. Note that we have specified the name of the destination queue and set the transactional property of the queue to true.

ReceiveMSMQ

Figure 9: Configuring the MSMQ Receive Adapter

 

The above figure shows the property window for the receive port using the MSMQ Adapter. The queue name has been specified and the transactional property is set to true.

In case of BizTalk Server 2004, the MSMQ Adapter needs to be downloaded. The adapter can be downloaded from here. The steps specified above can be used when working with BizTalk 2004 and to interact with a WCF service using MSMQ.

WCF Service Endpoint on NetTCPBinding

NetTCPBinding uses the Transmission Control Protocol (TCP) channel to interact with the client and service. There is no BizTalk adapter for TCP, hence the only option available while using the netTCP-bound endpoint is to employ the proxy pattern discussed below.

NetTCPBinding supports a duplex channel of communication – the service calls on the client interface to return the response without the client needing to listen explicitly.

Transactions

In order to execute a sequence of process steps as a transaction, the expression shapes should be in atomic transaction scope. Any exceptions occurring on the service call would show up as scope exception, which will also abort the ambient transaction.

Security

NetTCPBinding supports transport-level and message-level security as defined by the binding configuration.

Interoperability

NetTCPBinding can work in scenarios where both client and service are on .NET. The working of this sample for consuming WCF service exposed over a NetTCPBinding is as follows:

Detailed steps

  1. Define and implement the service contract as shown earlier.

  2. Create a console application to host the WCF service.

  3. Generate a proxy class using svcutil.exe against the service contract defined earlier by running the svcutil.exe tool as shown below. The assumption here is that the service is exposed at the URL https://localhost:8000/Service.svc. The URL should be replaced with the actual address of the service.

  4. svcutil.exe https://localhost:8000/Service.svc?wsdl

  5. Next step is to run the svcutil.exe against the WSDL and XSD files generated as a result of the command mentioned above.

  6. svcutil.exe *.wsdl *.xsd

  7. A proxy class and configuration file will generated.

  8. Add the generated app.config and proxy class to the Windows class library project and build the class library project.

  9. Create a BizTalk project which will contain the orchestration process. The sample code referenced in this article contains the actual orchestration.

  10. Add a reference to the class library we created from the BizTalk project. Declare an instance of the proxy class, which is present in the reference dialog box.

  11. Invoke the WCF service from within the expression shape in the orchestration:

  12. nettcpClient = new WCFServiceClient();
    intResult = nettcpClient.GetStockInfo(MsgInvRequest.Details.ProdID);
    
    
  13. Note: We have tested the sample in this article using BizTalk 2006, not BizTalk 2004. While the steps for both are the same, working with WCF on a BizTalk Server 2004 machine will require installation of the .NET framework 3.0. This is because a reference has to be added to a project that contains code generated using WCF.

  14. The following is the important section of the app.config for netTCPBinding:

  15. Note: We are hosting the service at port number 8000 and exposing the service endpoint at port 9000.

  16. <services>
    <service name="WCFService"
            behaviorConfiguration="WCFServiceBehavior">
        <host>
        <baseAddresses>
            <add baseAddress=<a runat="server" href="https://localhost:8000/service.svc">https://localhost:8000/Service.svc</a> />
        </baseAddresses>
        </host>
        <endpoint
        address="net.tcp://localhost:9000/netTCPWCFService/WCFService"
        binding="netTcpBinding"
        bindingConfiguration="Binding1"
        contract="IWCFService" />
        <endpoint address="mex"binding="mexHttpBinding"
                contract="IMetadataExchange" />
    </service>
    </services>
    
  17.  

  18. Note: In the following code snippet, we are specifying the transport-level security and the credential type:

  19. <netTcpBinding>
        <binding name="Binding1" …>
            <readerQuotas maxDepth="32"…/>
            <reliableSession ordered="true"…/>
            <security mode="Transport">
                <transport clientCredentialType="Windows"
                        protectionLevel="EncryptAndSign"/>
            </security>
        </binding>
    </netTcpBinding>
    

The app.config is as follows:


<client>
    <endpoint 
      address="net.tcp://localhost:9000/netTCPWCFService/WCFService"
      binding="netTcpBinding"
      contract="IWCFService" >
        <identity>
            <userPrincipalNamevalue="username@ad.infosys.com" />
        </identity>
    </endpoint>
</client>

 

In this approach explained above, we have a reference to the WCF proxy inside BizTalk. We are invoking the WCF-exposed service using the Expression shape.

The recommended approach is to send the message from BizTalk in plain XML format to a .NET wrapper class. This class will create a .NET object from within its implementation and then call the WCF proxy. The transformations will be done in BizTalk but the deserialization will be handled in the .NET assembly.

Message translation is best handled in BizTalk via the mapper and the rich set of functoids. Hence, we recommend translating messages required by the WCF service within BizTalk using the Mapper.

However, the WCF service may expect and return a .NET Type and not an XML. In such a case, converting the XML message is best done in the .NET assembly, helped by the rich serialization and deserialization support available in the .NET Framework.

The following table summarizes the same:

 

Done in Orchestration?

Done in .NET Assembly?

Transformation

Recommended (use BizTalk Mapper)

Not recommended. Is an implementation overhead

Serialization and
De-Serialization

Not recommended

Recommended

Exposing BizTalk Orchestrations as WCF Services

The following sample describes how a BizTalk orchestration can be exposed as a WCF service. The steps are:

  • Convert the orchestration to a web service using the orchestration Web Services Publishing Wizard.
  • Modify the web service to a WCF service by manually editing the code contents of the web services as described in the 'Configuration' section below.

Configuration

  1. Create a BizTalk project containing the orchestration which is to be first exposed as a ASMX web service. The orchestration process is as shown below and the actual code is present in the attached sample code:

  2. ExposeOrch

  3. Figure 10: BizTalk Orchestration to be exposed as WCF service

  4.  

  5. Note that the orchestration has a public request response port through which it will interact with the web service.

  6. Deploy the BizTalk project and run the BizTalk Web Services Publishing Wizard against the project.

  7. pub1

  8. Figure 11: BizTalk Web Services Publishing Wizard

  9.  

  10. pub2

  11. Figure 12: Selecting the BizTalk assembly to be exposed as service

  12.  

  13. pub3

  14. Figure 13: Selecting Orchestration Port that is to be exported

  15.  

  16. pub4

  17. Figure 14: Specifying properties for ASP.NET web service project

  18.  

  19. Once the orchestration is published as a web service, follow the steps below to convert the Web service into a WCF service. Both services can co-exist. This benefits existing clients since they can still make service calls via a regular Web service even as they use the WCF service. WCF-aware new clients can make WCF service calls.

    1. Open the BTS web service (created via the web service publishing wizard in previous steps) solution in Visual Studio 2005 (VS 2005).

    2. Add a reference to System.ServiceModel1. This namespace addition includes WCF in the solution

    3. In the code-behind file, add a reference to the System.ServiceModel namespace.

    4. Add the WCF ServiceContract attribute and give an appropriate namespace to the service contract:

    5. [ServiceContract(Namespace="http://Infosys.invoice/BTSWSasWCFService/")]

    6. Assign the ServiceContract attribute to the WCF service class that defines the service contract. The service contract defines the operations the WCF service is performing.

    7. Define the WCF OperationContract attribute for the web method defined in the following class:

    8. [OperationContract]
      public Invoice.XsdTypesBody.InvoiceResult
      Operation_1([System.Xml.Serialization.XmlElementAttribute
      (Namespace="http://Invoice.InvoiceSource", 
      ElementName="InventoryRequest")] 
      Invoice.XsdTypesBody.InventoryRequest part){…}
      
    9. Create a WCF Service file (.svc) and rename it to the same web service class name as the orchestration name. Add the following code snippet to the file:

    10. (<%@ ServiceHost Language="C#" Debug="false" 
      Service="Invoice.Invoice_InventoryProcessWS_Port_2" 
      CodeBehind="~/App_Code/Invoice_InventoryProcessWS_Port_2.asmx.cs" %>).
      
    11. Edit the web.config file to add WCF-specific XML tags as indicated below. This web.config file is created when the BizTalk orchestration is converted to a web service.

    12. <system.serviceModel>
      <services>
          <service name="Invoice.Invoice_InventoryProcessWS_Port_2"
              behaviorConfiguration="returnFaults">
          <endpoint address=""
              contract="Invoice.Invoice_InventoryProcessWS_Port_2"
              binding="basicHttpBinding" bindingConfiguration="Binding1" />
          </service>
      </services>
      
      <bindings>
      <basicHttpBinding>
      <binding name="Binding1" bypassProxyOnLocal="true">
      <security mode="None"/>
      </binding>
      </basicHttpBinding>
      </bindings>
      
      <behaviors>
      <serviceBehaviors>
          <behavior name="returnFaults" >
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          </behavior> 
      </serviceBehaviors>
      </behaviors>
      </system.serviceModel>
      
    13. Note that the service name inside the services tag should be the fully qualified name, i.e. with namespace, and should match the service in the WCF service (.svc) file.

    14. Build the solution

    15. Now, the BTS orchestration is exposed both as a web service as well as a WCF service that is ready to be consumed as shown below:

      • BTS as web service
        https://localhost/Invoice_Proxy/Invoice_InventoryProcessWS_Port_2.asmx
      • BTS as WCF service
        https://localhost/Invoice_Proxy/Invoice_InventoryProcessWS_Port_2.svc
  20. These services can now be consumed from a client. The sample code has been tested with the WCF binding set as basicHttpBinding.

Issues and Troubleshooting
  1. To add a web reference to a WCF service in a BizTalk project, we need to create the service using the File > New > Web Site option and select the WCF service template. WCF service cannot be created using New > Project option.

  2. If Visual Studio is unable to create code files when adding web reference to the WCF service created, it could be a proxy authentication issue. Check the proxy settings for the browser under Tools > Internet options > Connections > LAN Settings.

  3. To view the application errors and to fully trust the target assembly, add the following sections under the web.config file for all scenarios:

  4.  <system.web>
         <compilation debug="true"/>
         <customErrors mode="RemoteOnly"/>
         <trust level="Full" originUrl="" /> 
     </system.web>
    
  5. When sending messages from BizTalk to MSMQ we need to set the target namespace property of the schema to blank. If an instance of the schema is generated with the target namespace property specified, the WCF service is unable to process the message it picks up from MSMQ.

  6. For e.g., we can have a schema as follows:

  7. <ns0:InvoiceType>
      <InvNo>1</InvNo>
       <InvDate><strong>1999-05-31</strong></InvDate>
       <ProdID>2</ProdID>
       <Qty><strong>10</strong></Qty>
       <Price><strong>10</strong></Price>
       <StockAvail><strong>100</strong></StockAvail>
     </ns0:InvoiceType>
    
  8. And not as follows:

  9. <ns0:InvoiceType xmlns:ns0="http://Infosys.schemas">
        <InvNo>1</InvNo>
    <InvDate><strong>1999-05-31</strong></InvDate>
    <ProdID>2</ProdID>
    <Qty><strong>10</strong></Qty>
    <Price><strong>10</strong></Price>
    <StockAvail><strong>100</strong></StockAvail>
    </ns0:InvoiceType>
    
  10. When pointing to a remote MSMQ, the queue name needs to be specified in the following format:
    FormatName:Direct=OS:machinename\\private$\\queue
    Refer to this blog entry for more details.

  11. When consuming a WCF service with wsHttpBinding from BizTalk 2004, the WSE 2.0 Adapter is unable to understand the WSDL generated by the WCF service. The WSE 3.0 Adapter depends on .NET Framework 3.0 which has to be installed on the BizTalk 2004 system. It should solve the issue of consuming a WCF service with wsHttpBinding from a BizTalk 2004 application.

Conclusion

Creating services using Service-Oriented principles is key in many software projects and WCF is a very good framework for such a task. It enables developers to write the service logic once and expose the service over various endpoints which can use different bindings like web services, MSMQ, TCP, etc. Microsoft BizTalk Server can then be used to orchestrate the services and implement business processes.

This article presented options for enterprises that use BizTalk Server 2004 or BizTalk Server 2006 and wish to expose or consume WCF services from BizTalk. However, enterprises should look to upgrading to BizTalk Server 2006 R2 that will have native support and out-of-the-box adapters for communicating with WCF services. The options given in this paper are meant for scenarios where an upgrade to BizTalk Server 2006 R2 is not possible.

 

About the authors

Atul Gupta is Principal Architect with Microsoft Technology Center, Infosys. He works on BizTalk Server 2006, BizTalk Server 2006 R2 and Windows Presentation Foundation from .NET Framework 3.0 stack.

Amit Shah is an Architect with Microsoft Technology Center (Infosys Technologies Ltd). He is currently working on the creation of integration solutions on the Microsoft platform using technologies like BizTalk Server, .NET Framework 3.0, Office SharePoint Server 2007 and SQL Server 2005.

Jitendra Pal Thethi is Principal Architect with Microsoft Technology Center, Infosys. He is based out of Redmond and part of the Catalytic IT Solution Sales team and also the Infosys-MS Alliance team.

About the reviewers

Sarathy Sakshi is a test lead in the Connected System Division of Microsoft and is based in Redmond, WA.  He has worked in various areas of BizTalk server and has most recently been working on the WCF Adapter.

Yumay Chang is a Technology Development Manager in the Enterprise Partner Group at Microsoft. She leads the partner strategy on SOA and Business Process Management and supports partner in their adoption of Microsoft technologies.