BizTalk Orchestration And Web Services.

By BiZTech Know

This example shows how some business logic can be implemented by receiving a file into a BizTalk Orchestration and calling a Web Service. The results of the Web Service call are decided upon from the contents of the incoming file and the response message is constructed accordingly. The response message is also saved down to the local file system.

Calling a Web Service from a BizTalk Orchestration.

This example shows how some business logic can be implemented by receiving a file into a BizTalk Orchestration and calling a Web Service. The results of the Web Service call are decided upon from the contents of the incoming file and the response message is constructed accordingly. The response message is also saved down to the local file system.

Pre-requisites
This article assumes a good working knowledge of BizTalk, schemas, Maps and C# programming. As such some steps are shortened.

Construct and publish Web Service
Open Visual Studio and from the File menu select ‘New Web Site’. In the dialog that appears select ‘ASP.NET Web Service. Set the location to File System and accept the default location of C:\inetpub\wwwroot but name the project something meaningful like ‘POFromOrch’.

A default class called Service.cs will be created containing a simple ‘Hello World’ WebMethod. Replace the entire contents of this file with the following code:

using System;
using System.Diagnostics;
using System.IO;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using System.Xml.Serialization;

[WebService(Namespace = "http://ConsumeWebService/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
/// <summary>
/// Constructor
/// </summary>
public Service () {
}

/// <summary>
/// This is the object that gets sent from the Orchestration.
/// The class members match those in the InboundPO schema
/// </summary>
public class InboundPO
{
public string PO_Num;
public string PO_CustomerID;
public float PO_Total;
public string Date;
}

/// <summary>
/// This is the object passed back to the Orchestration.
/// The class members match those in the Invoice schema.
/// </summary>
public class Invoice
{
public string InvoiceNumber;
public string InvoiceCustomerNumber;
public float InvoiceTotal;
public float InvoiceDiscountedTotal;
public float InvoiceDiscount;
public string InvoiceDate;
}


/// <summary>
/// This is the WebMethod available to the Orchestration.
/// It accepts a PO object and returns an Invoice object.
/// </summary>
/// <param name="PODocument"></param>
/// <returns></returns>
[WebMethod]
public Invoice submitPO(InboundPO PODocument)
{
// Create a new Invoice document and set the InvoiceNumber equal to that of
// the incoming PO_Num
Invoice invoiceDocument = new Invoice();
invoiceDocument.InvoiceNumber = PODocument.PO_Num;
invoiceDocument.InvoiceCustomerNumber = PODocument.PO_CustomerID;
invoiceDocument.InvoiceTotal = PODocument.PO_Total;
invoiceDocument.InvoiceDiscountedTotal = GetDiscountedTotal(PODocument.PO_Total, PODocument.PO_CustomerID);
invoiceDocument.InvoiceDiscount = GetCustomerDiscount(PODocument.PO_CustomerID);
invoiceDocument.InvoiceDate = PODocument.Date;

return invoiceDocument;
}

/// <summary>
/// Some simplified business logic
/// </summary>
/// <param name="customerID">From incoming PO</param>
/// <returns>A number representing a discount percentage</returns>
private float GetCustomerDiscount(string customerID)
{
switch(customerID)
{
case "02468":
return 15;
break;
case "13579":
return 20;
break;
case "12345":
return 25;
break;
default:
return 0;
break;
}
}

/// <summary>
/// Some simplified business logic
/// </summary>
/// <param name="poTotal">From incoming PO</param>
/// <param name="customerID">From incoming PO</param>
/// <returns>A number representing the PO total minus any discount</returns>
private float GetDiscountedTotal(float poTotal, string customerID)
{
float discount = GetCustomerDiscount(customerID);
return poTotal * ((100 - discount)/100);
}
}

Now build the website and then publish it by selecting ‘Publish web site’ from the Build menu.

Now you have to enable the webservice. Open IIS and you should see the newly created website under Web Sites->Default Web Site. It will look like an ordinary folder. Right click it and select Properties. On the opening tab create the web service application by clicking the ‘Create’ button. Accept all other defaults.



Next we have to make the WebService run under .Net Framework 2.0 or later. To do this select the ASP.NET Tab at the top right. Select Framework 2 (or later) from the ASP.NET version dropdown.



Now when you view the WebService folder in the IIS Web Sites->Default Web Site tree it should have a WWW icon like the following image.



You can check that the webservice is now ready by right clicking on the Service.asmx file in IIS and selecting Browse. You should see something similar to the image below:


Now that the webservice is up and running the next thing to do is to create the BizTalk solution that will be using it.

Open Visual Studio and create a blank BizTalk solution.

Create client-side Schemas

Add the following schema to the BizTalk project and call it InboundPO.xsd


All nodes are of type string except for PO_Total which is a double.

Add another schema and call it Invoice.xsd. It should have the following nodes.



Allnodes are of type string except for InvoiceTotal, InvoiceDiscountedTotal and InvoiceDiscount which are all of type Double.

Add web reference

The next thing to do is to add a web reference to the web service we created earlier. To do this Right click the BT Project in Visual Studio and select ‘Add Web reference’.

In the dialog that appears search the local machine. You should then see the web service we created at the start of this article.



Click on the ‘Service’ link and you’ll see the WebMethod from the web service, as below


Click the ‘Add reference’ button to the right to add a Web reference to this web service.

Create maps
We next need to create two Maps. One will handle the transformation of the client side PO to  the web PO when requesting (calling) the web method. The other will handle transforming the response from the webservice from a web invoice to a client side invoice.

Client to Web PO Map
Right click the BT project and add a new map to the project. Call it ‘FilePOToWebPO.btm’. Set the source schema to the InboundPO schema and the destination schema to the web PO schema.



Connect the schema nodes as follows



Web to client Invoice Map
Right click the BT project and add a new map to the project. Call it ‘WebInvoiceToFileInvoice.btm’. Set the source schema to the web invoice schema and the destination schema to the client side Invoice schema.



Save the file as ‘WebInvoiceToFileInvoice.btm’.

Next we create the Orchestration that ties all of the previous elements together and gives shape to our business logic artefacts.

Right click the BT project in Visual Studio and add a new Orchestration called ‘ReceivePOandSubmitToWS.odx’. It will end up looking like the image below.



As you can see the Orchestration has a normal receive port, a normal send port but also a web request and response port.

To create the above orchestration, do the following:

Add message types

You need top add four message types to the orchestration. One each for the following:

Client side InboundPO

Add a new message to the Orchestration called InboundPOMessage and configure it with the properties set out below:


Client side Invoice
Add a new message to the Orchestration called InvoiceMessage and configure it with the properties set out below:



Note that the two Client side message types are derived from the client side schemas InboundPO.xsd and Invoice.xsd that you created earlier. When you added the web reference to the web service created earlier, BizTalk automatically added a Web message type for the request and response for the web service. When you create the server side message types make sure you reference the correct type (Request or Response) by navigating to the Web Message Type folder in the message properties box.



Bearing this in mind, now add the two server side meaages

Server side PO Message
Add a new message to the Orchestration called WebServicePOMessage and configure it with the properties set out below:



Server side Invoice Message
Add a new message to the Orchestration called WebServiceInvoiceMessage and configure it with the properties set out below:



Add Receive port
Add a receive port to the orch and configure as set out below:



Add web port
Add a Request and Response web port and configure it as follows:



When configuring the web port make sure to select an existing port type and choose the one under Web Port Types. This was also added automatically when you added a web reference to the web service.



Add Receive shape
Drag a Receive shape onto the orch and configure it as below:



Add Construct PO Message shape
Add a construct message shape to the orch and configure it as follows:



Add transform PO message shape
Add a transform message shape inside the Construct PO Message shape and configure it as follows:



Make sure to reference the existing map FilePOToWebPO.btm you created earlier

Add send PO to Web Service shape
Add a send shape to the orch and configure it as below:


Add Receive Web Invoice shape
Add a Receive shape to the Orch and configure it as below:



Add Construct invoice message shape
Add a construct message shape to the orch and configure it as follows:



Add transform shape into the Construct Invoice Message shape
Configure the Transform as follows:


Make sure to reference the existing map WebInvoiceToFileInvoice.btm you created earlier.

Add send invoice shape
Add a send shape to the Orch and configure it as follows:



Add Send port
Add a send port to the orch and configure as set out below:



That’s the Orchestration finished. Make sure you give the project a strong name then build and deploy the project. Make sure you configure the hosts and start the application.

All we need to do now is create the test files we will use to drop into our BizTalk aware inbound folder and drop them in to see the result in our output folder.

Create test files


I created 4 test files. 3 will return a discounted Invoice total and one will not. This simulates (rather simply) 3 cutomers who receive discounts and one which does not.

Using your favourite text editor construct the following 4 messages:

PO_02468.xml

<ns0:InboundPO xmlns:ns0="http://ConsumeWebService.InboundPO">
<PO_Num>PO_00001</PO_Num>
<PO_CustomerID>02468</PO_CustomerID>
<PO_Total>100</PO_Total>
<Date>07/06/2010</Date>
</ns0:InboundPO>

PO_12345.xml
<ns0:InboundPO xmlns:ns0="http://ConsumeWebService.InboundPO">
<PO_Num>PO_00002</PO_Num>
<PO_CustomerID>12345</PO_CustomerID>
<PO_Total>100</PO_Total>
<Date>07/06/2010</Date>
</ns0:InboundPO>

PO_13579.xml
<ns0:InboundPO xmlns:ns0="http://ConsumeWebService.InboundPO">
<PO_Num>PO_00003</PO_Num>
<PO_CustomerID>13579</PO_CustomerID>
<PO_Total>100</PO_Total>
<Date>07/06/2010</Date>
</ns0:InboundPO>

PO_NoDiscount.xml
<ns0:InboundPO xmlns:ns0="http://ConsumeWebService.InboundPO">
<PO_Num>PO_00004</PO_Num>
<PO_CustomerID>99999</PO_CustomerID>
<PO_Total>100</PO_Total>
<Date>07/06/2010</Date>
</ns0:InboundPO>

Drop test files
Drop each one in turn into the configured inbound folder and then examine the outbound messages in your outbound folder.

Below is an example invoice created in response to PO_13579.xml. Notice the InvoiceTotal is 100, the InvoiceDiscount has been calculated as 20 leaving a DiscountedInvoiceTotal of 80.

<?xml version="1.0" encoding="utf-8"?>
<ns0:Invoice xmlns:ns0="http://ConsumeWebService.Invoice">
<InvoiceNumber>PO_00002</InvoiceNumber>
<InvoiceCustomerNumber>13579</InvoiceCustomerNumber>
<InvoiceTotal>100</InvoiceTotal>
<InvoiceDiscountedTotal>80</InvoiceDiscountedTotal>
<InvoiceDiscount>20</InvoiceDiscount>
<InvoiceDate>23/05/2010</InvoiceDate>
</ns0:Invoice>

This example shows how to call a WebService from an Orchestration and perform some desired business logic. In reality a more complex process would be carried out but I hope this article shows some of the simple principals that can be expanded upon to produce powerful, web-aware applications.

Happy BizTalking!





Popularity  (3538 Views)
Create New Account
Article Discussion: Calling a Web Service from a BizTalk Orchestration.
BiZTech Know posted at Saturday, June 05, 2010 1:42 PM
reply
Amit replied to BiZTech Know at Saturday, June 05, 2010 8:54 PM

dear sir,

how we can acheive versioning in this case?

I have on biztalk application which calls webservice from orchestration. this is my version 1 application. i modified the same and created the version 2 application of the same which will call the same web service but different method on that web service.

i deployed both the vereion and first check the vrsion 2 only by dropping files and it works fine.
but when i checked version 1 by dropping files it fails and give me the below error
Microsoft.XLANGs.Core.UnexpectedMessageTypeException: Received unexpected message type.
the total error message is
Microsoft.XLANGs.Core.UnexpectedMessageTypeException: Received unexpected message type 'LSC.FundingData.Import.DLF.Orchestrations.SSoADataImportService.Reference+AdultSSoAData, LSC.FundingData.Import.DLF.Orchestrations, Version=2.0.0.0, Culture=neutral, PublicKeyToken=82632b94b069a919' does not match expected type 'LSC.FundingData.Import.DLF.Orchestrations.SSoADataImportService.Reference+AdultSSoAData, LSC.FundingData.Import.DLF.Orchestrations, Version=1.0.1.0, Culture=neutral, PublicKeyToken=82632b94b069a919'.
at Microsoft.XLANGs.Core.XMessage._verifyPublisherSchema() at Microsoft.XLANGs.Core.XMessage.FetchProperties() at Microsoft.BizTalk.XLANGs.BTXEngine.BTXPortBase.ReceiveMessage(Int32 iOperation, Envelope env, XLANGMessage msg, Correlation[] initCorrelations, Context cxt, Segment s) at LSC.FundingData.Import.DLF.Orchestrations.DLFAdultFundingDataImport.segment6(StopConditions stopOn)
at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)
Microsoft.XLANGs.Core.UnexpectedMessageTypeExceptionScoped@
DLFAdultFundingDataImport.??__scope34
DLFAdultFundingDataImport.??__scope33
DLFAdultFundingDataImport.DLFAdultFundingDataImport
20d2d333-4794-4976-a37d-21544dfe0587

as per my understanding when orchestration sends message to webservice and getting reply back from web service there are two subscriber for response one is version 1 orch adn second is version 2 orch and by default it is picking up by the second latest version orch.
if that is right can you help me to solve this?
i want to run both the version side by side ...
i tried all the option but its not working properly need help on this...

right now i am creating the new web service which will call by the version 2 orchestration... but its not a ideal solution ...
can you please help me with solution for this...

reply