5,692,513 members and growing! (19,312 online)
Email Password   helpLost your password?
Enterprise Systems » Microsoft BizTalk Server » General     Intermediate

Building BizTalk Server 2006 Currency Converter Custom Functoid

By Kareem Shaker

You will learn how to build BizTalk Server 2006 Currency Converter Custom Functoid using a WebService, and you will get an introduction about standarad functoids.
XML, Windows, Visual Studio, Dev

Posted: 11 Aug 2006
Updated: 11 Aug 2006
Views: 37,381
Bookmarked: 19 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
17 votes for this Article.
Popularity: 5.74 Rating: 4.67 out of 5
1 vote, 5.9%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
2 votes, 11.8%
4
14 votes, 82.4%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Contents

Introduction

BizTalk Server 2006 has around 80 functoids, or functions, these functoids are helpful while building your maps; more about that later. BizTalk Server 2006 Mapper IDE is the same as VS.NET 2005 IDE; when you build a map you will be inside the same environment that you are used to, and if you open a map, the functoids toolbox will display all standard and custom functoids, the standard functoids are categorized in a neat way based on the functionality of each, but sometimes the functoids library you have is not enough, so you will opt to build your own functoid, in this article, I will give you an introduction about BizTalk Server 2006 Mapper, and I will try to explain and boil down the standard functoids provided by BizTalk Server 2006, giving one practical example about Database Lookup functoid, then we'll go through building a custom functoid after we examine the architecture of custom functoids; the functoid we'll build is a Currency Converter functoid, I tried to propose a useful and reusable functoid that you may use later, this functoid is built upon a web service that provides currency rates, Also you will learn how to install your functoid into the GAC ( Global Assembly Cache ), and add it to your toolbox, so let's start our journey with functoids.

Knowledge Prerequisites and Software Requirements

  • Knowledge
    • BizTalk Server core principals; such as messaging, how to create schemas, maps,etc.. I will try to explain these concepts as much as I can, but if you have prior experience it will be fine.
    • WebServices core principals.
  • Software Requirements 
    • Visual Studio.NET 2005.
    • BizTalk Server 2006, these are my versions, I think you can use VS.NET 2003, and BizTalk 2004.

BizTalk Server 2006 Mapper

BizTalk Mapper is just a tool to define relationships between an input source schema and a destination schema, in other words it binds elements, attributes, records, etc.. to one another using a polished designer, right inside VS.NET 2005, you can directly connect one field element to any other schema element, or you can process the input data then you send it to the destination element; the processing is maintained using Functoids, for example if the destination schema allows only Name field element, while the source schema has two fields for the name, one is the firstName, second is the lastName, you can use a String Concatenate functoid, that accepts first and second names, it actually accepts from 1 to 100 parameters,  then you can create a link from this functoid output to the destination schema element, which is Name in this case.

BizTalk saves a map in a .btm ( BizTalk Map ) file extension, and this is an XML based file, if you are curious, like me, open it in any XML editor or even in notepad, you will find out that everything about the map is stored inside, you will find XML nodes and elements about everything on the design surface, including Links, Functoids, Input Parameters, Pages, Source and Destination schemas, etc.., Pages are design pages that you use when your map gets sort of spaghetti, and you need to organize your links, it's a good practice to keep direct links in one page, and functoid based links in another page, this would be more comprehensive, and once your map is built, it's getting converted to XSLT file; a link is provided at VS.NET output window you can open the XSLT file and view its contents.

BizTalk Mapper

Fig01 : BizTalk Server 2006 Mapper

Basically, maps are used for two purposes Translation and Transformation of Messages, Translation is just about Message Format, while Transformation is all about Data, in other words; when you use a map to change the format of a message from one to another you are doing Translation, consider translating one message from flat file format to XML format, Transformation is copying data between schemas using maps, if you have one source schema that contains a Salary data element, and you need to copy this salary value from Human Resources department application to another department such as Finance, this is what we mean by Transformation.

BizTalk Server 2006 Standard Functoids

In this section I will give a brief about Standard Functoids included in the Functoids toolbox, some functoids are self-explanatory while others somehow need some clarification

Functoids Category Description Notes
String Common string operations, as trimming, extracting substrings, getting index of one string within another, case conversion, concatenation, etc.. All string operations are 1-based index
Mathematical +, -, *, /, %, Min, Max, Round, Square, Square Root, etc.. Round is a bank or even rounding, 4.5 rounds to 4; all .5 numbers will give the nearest even number
Logical >, <, =>, <=, !=, ||, &&, !, IsNil, Logical Date, Numeric, String, Existence Logical Date checks if input could be date, inputs may be string, numeric, boolean, and they are converted at runtime to boolean, while output is always boolean. non-zero numberic inputs are considered True, while a zero represents false, if the inputs are strings comparing inputs is case sensitive comparison; so c is not equal to C
Date/Time Date, Time, Date and Time, Add Days Time in 24 hrs format, and Add Days take a date in ISO-8601 format
Conversion Octal, Hexadecimal, ASCII to Char, Char to ASCII  
Scientific Sine, Cosine, Tan, ArcTan, Logn, Log10, Ln, Pow, e, etc.. Trigonometric functoids use radians not degrees
Cumulative Cumulative Concatenate, Sum, Minimum, Maximum, Average; input should be  link from a Record, Field Element, or Field Attribute node, the function of this category is to process a recurring group of schema element, using scope, default is 0 that manages the whole message There is second input parameter called Scope, determines elements to be accumulated, it's optional parameter, default value is zero that accumulates the entire message.
Database Contains Database functoids and Cross Referencing Functoids, Database functoids are Database Lookup, Value Extractor, Error Return, all other functoids in this category are Cross Referencing Functoids.
Error Return and Value Extractor functoids are used in conjunction with Database Lookup, which returns first matching row from an ADO.NET recordset.
Value Extractor is used to get a column value from the Database Lookup functoid output, and Error Return is used to hold any exception message thrown at runtime which can be written to destination schema node.
Advanced Value Mapping, Looping, Table Extractor,  Assert, Iteration, Index, Mass Copy, Scripting, etc.., the Mass Copy functoid is used to copy an element including all or some of its sub elements, on the other hand Conditional Mapping is acting like Intermediate If or famous IIF.
Record Count, Table Looping, and similar looping functoids are used to manage unpredictable number of repeating elements.
Assert is used for the sake of troubleshooting it makes sure one value is true at runtime, also Scripting is important as it calls script or compiled code when used

Cross Referencing Functoids , these functoids use data stored in BizTalkMgmtDb, The Configuration wizard creates these tables during configuration, you can find them in the BizTalkMgmtDB database; they are 9 tables prefixed with xref_ , but the tables stay empty until you fill them out from 9 XML files, this will get the database tables filled in, and if you don't fill these table you will not be able to use this set of functoids, if you try you will get exceptions.
BTSXRefImport.exe is the import utility to copy data from the XML documents to the database tables, this document will show you how to import XML files, Importing Data for the Cross Referencing Functoids, actually MSDN is somehow unclear regarding setting up database tables for the cross referencing functoids, and you will not find examples in MSDN with enough elaboration, however I didn't import these files into the database, I will try to do that later and post to everyone, but basically the cross referencing is used when you have ,for example, an OrderID which travels from an application to another and it is differs in these different applications, so you can hold the IDs in the management DB; and look up the destination ID in the management database, suppose the Order Status in system A is OrderSent, it may be OrderSubmitted in System B; so you use cross referencing to lookup the new Status value of system B, also you will need to fill the XML files adhering to the schema supplied at MSDN before using the import tool, also I couldn't find any way around to reset these tables, any suggestions from you would be helpful, until Microsoft enhances documentation of Cross Referencing.

Functoids Configuration

As we have seen above a functoid takes some input parameters; these parameters need to be configured, to inform the functoid how to operate based on these input parameters, in the following section we'll view a simple example that looks up some data from a database, based on one ID passed, so we'll use Database Lookup Functoid, with Value Extractor and also we'll add the Error Return functoid to the map to demonstrate how to use these three functoids together.

Let's say that you have a group of stores, that are managed only by one headquarter, and this headquarter can send a PO to any affiliate that could get merchandise from a store specified by the headquarter, all communication is only between the headquarter and the affiliate, so the headquarter schema lookup the database by passing the StoreID, from which affilate will collect merchandise, to a Database Lookup functoid, and then to extract data to be sent to affiliate, we will start using Value Extractor functoid to extract specific field value from returned recordset, and for handling unexpected errors like syntax and connection failures or timeout, we'll add an Error Return functoid that will write the exception details to the destination schema.

For the sake of simplicity we'll use the Pubs database, and we will lookup Stores table.

You will need to create two schemas, first is Headquarter.xsd and the second is Affiliate.xsd, then you will need to create a new map call it Affiliate.btm, details for the schemas and the map are shown in the following screen

Database Lookup Functoid Map

Fig02 : Affiliate Map, source is Headquarter schema and destination is Affiliate schema

Now, you should configure the functoids added to the map, for this example we'll configure the database lookup functoid, you can double click it, or select the input parameters from the properties window, you will get the modal dialog box, Configure Functoid Inputs, and you will get a good description about the number of parameters to be added, if you try to add more you will not be able to do so, as once you reach the number of allowed input parameters the new input parameter button gets disabled.

Database Lookup Functoid Input Parameters Configuration

Fig03 : Configuration of input parameters for Database Lookup Functoid

The first parameter is the expression to extract lookup value from source schema and it is built by Mapper, second is the database connection string, and it's strongly recommend to use windows integrated security, third is table name, fourth is the column name, you can configure the rest of functoids easily, Value Extractor functoid will take only the column name, it will extract the value of one column from the database lookup functoid.

After building schemas, maps, now you need to build an input file to provide to Affiliate map to be tested, we'll build a simple XML file, call it Headquarter.xml and these are the contents of the file ( included in code download ).

<ns0:Headquarter xmlns:ns0="http://FunctoidConfigurations.Headquarter">
 <Store StoreID="StoreID_0" /> 
</ns0:Headquarter>

Now, we need to provide this file to the map to let the map use it while testing, right click Affiliate.btm from solution explorer and select Properties, this will open the map property pages, Select TestMap Input file and browse to Headquarter.xml.

Now, you are ready to test your map, right click the Affiliate.btm from solution explorer and select Test Map , after few seconds you will get some output messages at the output window, and you will get a link to input and output files generated after testing the map, if you open the output file it should be like this

<ns0:Affiliate xmlns:ns0="http://FunctoidConfigurations.Affiliate">
<Store StoreName="" Zip="">
<StoreAddress></StoreAddress>
<City></City>
<State></State>
<ErrorMessage></ErrorMessage>
</Store>
</ns0:Affiliate>

As you see the output is empty since we don't have in the stores table one store id value "StoreID_0", now we willl change the StoreID value in source schema to "6380"; this is a value that exists in Stores table, then we can test again, this time you will get the details of store id 6380

<ns0:Affiliate xmlns:ns0="http://FunctoidConfigurations.Affiliate">
<Store StoreName="Eric the Read Books" Zip="98056">
<StoreAddress>788 Catamaugus Ave.</StoreAddress>
<City>Seattle</City>
<State>WA</State>
<ErrorMessage></ErrorMessage>
</Store>
</ns0:Affiliate>

As you can see, the Database Lookup Functoid extracted all the fields for the input store id, in case the recordset includes more than one record; the first matching records is the one that's used.

Now, we'll force the Database Lookup functoid to throw an exception, simply go to the Configuration of Database lookup functoid and append 'X' to the database table name, now the database table name is 'storesX', try to test the map again ,and let's see what will happen, open the output file you will get this XML output

<ns0:Affiliate xmlns:ns0="http://FunctoidConfigurations.Affiliate">
<Store StoreName="" Zip="">
<StoreAddress></StoreAddress>
<City></City>
<State></State>
<ErrorMessage>Invalid object name 'storesX'.</ErrorMessage>
</Store>
</ns0:Affiliate>

Since, the table name is invalid, you will not get any data into the destination schema, and you will get a meaningful error message that explains the reason behind getting no data, so it's advisable to use Error Return Functoid!

Custom Functoids Architecture

Now, we are done with the standard functoids, and we will move to another stage of functoids; building a custom functoid, basically you opt to this solution when you don't find a a standard functoid that covers your needs.

The functoid that we are going to build is a Currency Converter Functoid, and here we should mention some words about what the functoid should and shouldn't do, when to use it and not to use it, actually this has been an architectural argument among technology specialists, some say maps are just about mapping and no business processing should be done inside maps, and all data processing should be done at orchestration, while the others encourage and support processing data at the map level, and their evidence is the standard Database functoids included in the functoids group, however you should decide when to use a custom functoid and whether it will affect performance heavily, it's simply a matter of design and performance too, but for this CurrencyConverter functoid, I think it's helpful and it's right to encapsulate this functionality inside one reusable functoid, for the above example we can send to Affiliate the store currency, supposing stores are distributed around the globe, and also the rate of this local currency in USD, here the importance of our custom Currency Converter functoid comes to light!, actually I have seen around some EAI solutions require currency conversions.

Functoids are just a .NET compiled code included, of course, inside one or more assemblies, custom functoid should inherit from a BaseFunctoid class that's contained in Microsoft.BizTalk.BaseFunctoids namespace, this namespace maps to one assembly which is Microsoft.BizTalk.BaseFunctoids.dll, located at Developer Tools folder under your installation folder, to create a custom functoid we'll override some overridable methods in the base class.

Custom Functoids Design

Let's examine what we've done in the above Database Lookup Functoid, to know what we'll need to create our Currency Converter Custom Functoid, before you drag a functoid to a design surface, you first spot a category under which your functoid located, then you find your functoid Name, preceded with a 16x16 Bitmap, once you move your mouse over it you get a tooltip, also you will need to supply a Description to your functoid, you will need to supply one ID, greater than 6000 as recommended by Microsoft, the description is so important and I strongly recommend that elaborate as much as you can, I tried to provide a description similar to standard functoids descriptions.

Once you place the functoid into the design surface, the user will start to provide Input Links, so we need to define Minimum and Maximum Number of Input Parameters, functoids accept specified types of input parameters and outputs to specified types of schema elements, so we also need to define acceptable Input Connection Types, and Output Connection Types, at runtime the mapper calls your functoid so you should provide one name to the mapper that identifies your functoid, and this is mandatory for functoids that are planned to be deployed into GAC, you assign this name by calling SetExternalFunctoinName, so this sets an External Name for your custom functoid.

That was for the class that will encapsulate the functoid as a component, but for the implementation we will need to refer to the webservice that will provide the currency conversion, also we will need to build a resource file to hold strings and bitmaps required for the functoid.

You can check the webservice at CurrencyConverter, we are going to add a web reference to this webservice, the WSDL contract is available at Currency Converter WSDL, as we'll deploy the functoid into GAC, we need to provide a strong name key file to it, or to digitally sign our assembly, so we'll need to create an SNK file, which we will discuss in the following section.

Currency Converter Functoid Development

In this section we will build our functoid, we will write code, draw a bitmap, build a resource file, and create a new SNK file, this section is kind of a walkthrough.

Create a new Class Library Project, and name it BusinessFunctoids, rename the default class file to CurrencyConverter.cs, first we will add all the normal and web references we need to develop our functoid.

Adding Required References

As mentioned earlier that our class will inherit from BaseFunctoid class, this class belongs to Microsoft.BizTalk.BaseFunctoids.dll assembly, you can locate it at C:\Program Files\Microsoft BizTalk Server 2006\Developer Tools, or it should be under Developer Tools installation folder, you can add a reference to this assembly by right clicking references from Solution Explorer and add a reference to this assembly so you will be able to use BaseFunctoid class.

To consume CurrencyConverter webservice you will need to add a web reference to your project, you can do that by right clicking your BusinessFunctoids class library project and selecting Add Web Reference, this will bring the Add Web Reference Window, you should enter the URI of the CurrencyConverter Webservice which is http://www.webservicex.net/CurrencyConvertor.asmx?WSDL, now you are ready to start developing your custom functoid.

Creating Strong Name Key File

To Deploy our Currency Converter Functoid into GAC, we need to digitally sign the assembly to expose it to the entire system, however in VS.NET 2003 you had to run the Visual Studio Command Prompt from Visual Studio.NET Tools, and you could use sn command, this way still works in VS.NET 2005. to create a new snk file, open the VS.NET command prompt and type

sn -k BusinessFunctoids.snk

This will create the snk file to the location where you run the command from; if you are at C:\ and you run your command the file will be written to C drive, now you need to expose your snk file to the class library project; right click BusinessFunctoids project from Solution Explorer, select Properties, select Signing Tab from the left panel, check Sign the assembly, from the dropdown list you can browse and select the file you've created using the above command, or you can select New to create a new SNK file right from VS.NET 2005 and directly associate it to the project, the later way is more elegant.

Building Assembly Resource File

To provide resources to Currency Converter functoid , we need to create a new resource file that will hold all the strings needed for Currency Converter Functoid, and also it will hold a 16x16 bitmap icon for the functoid, one odd thing about VS.NET resource designer is that it only supports string manipulations and if you want to add a picture to the resource file; it will not allow you to do so, so I often use an external tool to add a bitmap to a resx file, it's Resource Editor.NET, another stunning tool provided by CodeProject community member! , open the resx file and supply these values, then add currencyicon.bmp to the resx file, the description tells everything about the functoid, how many parameters required and explanation about parameters.

Name Value
IDS_CURRENCYFUNCTOID_DESCRIPTION Use the Currency Converter Functoid to convert one field value from a source currency to another foreign currency. The input parameters are 3 parameters: fromCurrency, toCurrency, input field, input currencies should be in ISO code format.
IDS_CURRENCYFUNCTOID_NAME Currency Converter
IDS_CURRENCYFUNCTOID_TOOLTIP Currency Converter
IDI_CURRENCYFUNCTOID_ICON Select currencyicon.bmp from Resource Editor.net

CurrencyConverter Functoid Implementation

In this section we'll write the code for our functoid, our code is divided into two sections; first is the functoid constructor, that calls the base constructor, and its objective is to define the functoid to the mapper toolbox, let's examine the constructor code

    1 using System;
    2 using System.Collections.Generic;
    3 using System.Text;
    4 using Microsoft.BizTalk.BaseFunctoids;
    5 using System.Reflection;
    6 using System.Globalization;
    7 using BusinessFunctoids.net.webservicex.www;
    8 
    9 namespace BusinessFunctoids
   10 {
   11     ///<summary>

   12     /// CurrencyConverter inherits BaseFunctoid 

   13     ///</summary>

   14     publicclassCurrencyConverter : BaseFunctoid
   15     {
   16         ///<summary>

   17         /// This is the defualt constructor that conveys to the toolbox.

   18         ///</summary>

   19         public CurrencyConverter()
   20             : base()
   21         {
   22             this.ID = 6500;
   23             // this to get the resources embedded in the resx file, 

        //and we call GetExecutingAssembly because

   24             // the resource is compiled and embedded into the DLL.

   25             SetupResourceAssembly("BusinessFunctoids.BusinessFunctoidResources",
         Assembly.GetExecutingAssembly());
   26 
   27             // Setting the functoid with resources inside resx file

   28             SetTooltip("IDS_CURRENCYFUNCTOID_TOOLTIP");
   29             SetBitmap("IDI_CURRENCYFUNCTOID_ICON");
   30             SetName("IDS_CURRENCYFUNCTOID_NAME");
   31             SetDescription("IDS_CURRENCYFUNCTOID_DESCRIPTION");
   32 
   33             // Accepts 3 Params, source currency, destination currency, price.

   34             this.SetMinParams(3);
   35             this.SetMaxParams(3);
   36 
   37             // this method call lets the mapper what function to call, when functoid

   38             // is deployed to GAC, ConvertCurrencyField is the method we'll include later.

   39             SetExternalFunctionName(GetType().Assembly.FullName,
             "BusinessFunctoids.CurrencyConverter", "ConvertCurrencyField");
   40 
   41             // defining category in toolbox, 

        //this decides under which category the functoid will be added.

   42             this.Category = FunctoidCategory.Conversion;
   43 
   44             //define output and input connection types..

   45             this.OutputConnectionType = ConnectionType.AllExceptRecord;
   46             AddInputConnectionType(ConnectionType.AllExceptRecord);
   47 
   48         }
The code is self-explanatory, in line 22 you supply the ID to our functoid, code from 28-31 sets resources required for the toolbox, 34-35 to decide how many parameters valid for the functoid, 39 sets the external function name, 42 assigns the category under which the functoid will appear, 45-46 set output and input connections types.

Line 25, calls SetupResourceAssembly base method that takes 2 parameters, first is the resource file name, second is the assembly.

The following section demonstrates the concrete functoid logic, that converts one input field from one currency to another using the CurrencyConverter webservice

   50         public string ConvertCurrencyField(string fromCurrency, 
		string toCurrency, string field)
   51         {
   52             decimal numericField,result = 0m;
   53             double rate;
   54 
   55             if (IsNumeric(field))
   56             {
   57                 try
   58                 {
   59                     numericField = 
                Convert.ToDecimal(field, System.Globalization.CultureInfo.InvariantCulture);
   60           BusinessFunctoids.net.webservicex.www.CurrencyConvertor ws_Converter;
   61           	ws_Converter = 
				new BusinessFunctoids.net.webservicex.www.CurrencyConvertor();
   62 
   63           rate = ws_Converter.ConversionRate(
   64                  (BusinessFunctoids.net.webservicex.www.Currency)
                       Enum.Parse(typeof(BusinessFunctoids.net.webservicex.www.Currency),
			 fromCurrency),
   65                   (BusinessFunctoids.net.webservicex.www.Currency)
                        Enum.Parse(typeof(BusinessFunctoids.net.webservicex.www.Currency),
			 toCurrency)
   66                         );
   67 
   68                     result = Convert.ToDecimal(rate) * numericField;
   69                     
   70                 }
   71                 catch (Exception ex)
   72                 {
   73                     throw ex;
   74                 }                               
   75             }          
   76             return result.ToString();
   77         }               

The above method is the core method, it's the functoid that will process everything, it's designed to take 3 parameters fromCurrency, toCurrenty, and field; the field is the amount or number to be converted, and you should consider that everything is a string in terms of the mapper, that's why we pass strings to our functoid, the mapper doesn't manipulate data types conversion, moreover the arguments should be strings, and the return as well, the function should be public to let the mapper call it, from inside you should check for the data type of input arguments, it's sort of more data type verification because the schema validates the input values based on the schema definition.

The code is self-explanatory and you should know from WSDL and provided examples in webservice's website that it expects currencies in ISO format, and there is a Currency Enumerator that holds all supported currencies, it's better to hold code between try-catch block since we're calling an external webservice, lines 63-66 makes a call to the webservice passing the enumerated currency codes, then we have the rate, which is the most important value we need, line 68-69 calculates the field in destination currency as per the rate value, then we return the value after casting it to string.

Congrats !, you've finished developing your Currency Converter Functoid, and the remaining sections are focused on deployment, and testing the functoid.

Adding Currency Converter Functoid to Toolbox

When Mapper starts it checks one folder to and loads any functoids assemblies inside this folder, this folder is Mapper Extensions folder under Developer Tools folder, you need to copy your built functoid assembly BusinessFunctoids.dll to this folder, now you can add Currency Converter functoid to VS.NET functoids toolbox, open a map in VS.NET to get Functoids toolbox, then from Tools menu select Choose Toolbox Items, select Functoids tab, then browse to the Mapper Extensions folder in which you've copied BusinessFunctoids.dll before, select BusinessFunctoids and press OK, you will get the icon of CurrencyConverter functoid in the lower part of the window, click OK, focus will go to Currency Converter functoid under Conversion category.

Registering Currency Converter Functoid to GAC

Currency Converter is a global functoid that will be called by mapper so we need to deploy it to Global Assembly Cache using the VS.NET 2005 command prompt, open VS.NET 2005 command prompt and browse to Mapper Extensions folder and enter the following to register Currency Converter functoid into global assembly cache

gacutil /if BusinessFunctoids.dll

If the process goes smoothly, you will get Assembly Successfully added to the cache , if you want to assure that the assembly is added to the GAC, browse to Windows Installation directory and then to assembly directory, try to spot BusinessFunctoids assembly, if it's there so everything is fine, and the assembly is physically installed in the GAC.

Currency Converter Functoid Consumption

Now is the time to use the currency converter functoid, we'll create two schemas and one map, suppose that an exporter is selling products to foreign importers, the exporter is supposed to send the prices in foreign importer currency, for this purpose you will need to create a new empty BizTalk Server project call it CurrencyFunctoid, and add a new schema file, call it ExporterSchema.xsd and rename the root node to ExporterOrder, right click this node and select Insert Schema Node -> Child Record, rename it to Order and set Min Occurs and Max Occurs properties to 1, right click Order node and select Insert Schema Node -> Child Record, rename it to Item and set Min Occurs to 1 and Max Occurs to * (unbounded), then add the following fields to Item record

Field Name DataType
Attribute currency xs:string
Attribute foreignCurrency xs:string
Element price xs:decimal
Element quantity xs:unsignedInt
Element productCode xs:string

Add a new schema file to the project, call it ImporterSchema.xsd, rename the root node to Order, right click this node and select Insert Schema Node -> Child Record, rename it to Item and set Min Occurs to 1 and Max Occurs to * (unbounded), add the following fields to the Item record

Field Name DataType
Attribute PId xs:string
Attribute quantity xs:unsignedInt
Element price xs:decimal


Create a new map to the project and name it CurrencyConversion.btm, set the source schema to ExporterSchema, and the destination to ImporterSchema, make a direct link from productCode to PId, and from quantity to quantity, then drag Currency Converter functoid from toolbox, it should be under conversion category, once you place it on the design surface, you can get the Configure Functoid Inputs either by double clicking it or by clicking ellipsis button next to the Functoid Inputs in properties windows, in the configuration window you will be able to enter only 3 parameters, also you will get the description you've entered before in the resource file into the Functoid description label, close the window without adding any parameters, and drag currency, foreignCurrency, and price nodes into the Curreny Converter Functoid respectively, these will serve as input parameters to the Currency Converter Functoid, double click the functoid and it should look like this 

Currency Converter Functoid Configuration

Fig04 : Configuration of input parameters for Currency Converter Functoid

Go to the design surface and drag a link from the Currency Converter functoid to the price element in the destination ImporterSchema, this will write the result into this element. After, creating the map it's ready to be tested, for testing we'll use Map_test_Input.xml available in the code download, this is the content of the input XML message
<ns0:ExporterOrder xmlns:ns0="http://CurrencyFunctoid.ExporterSchema">
 <Order>
 <Item currency="USD" foreignCurrency="EGP">
 <price>10.4</price>
 <quantity>10</quantity>
 <productCode>productCode_0</productCode>
 </Item>
 </Order> 
</ns0:ExporterOrder>
The input currency is USD and destination currency is EGP (Egyptian pound), suppose the exporter in United States and the importer at Egypt, to provide this input test file to the map, right click CurrencyConversion.btm from solution explorer, select Properties, select TestMap Input Instance, click ellipsis button and browse to Map_test_Input.xml, click Open and then OK, right click CurrencyConversion.btm map from solution explorer and select Test Map, the output window will show and after testing the map you will get a link to an output file in the output window, press CTRL+Click to open it in VS.NET, you will get the following output message
<ns0:Order xmlns:ns0="http://CurrencyFunctoid.ImporterSchema">
 <Item PId="productCode_0">
 <quantity>10</quantity>
 <price>59.7272</price>
 </Item>
 </ns0:Order>
Congrats, the price is in foreign currency, if you divide 59.7272 by 10.4 you will get 5.743 which is the rate of USD against Egyptian pound.

Using Code

Code download contains one solution CurrencyFunctoid, and three projects, first is class library BusinessFunctoids that contains the CurrencyConverter functoid, second is CurrencyFunctoid that serves as a test application for the custom CurrencyConverter functoid, third is FunctoidConfigurations, this is the Database Lookup functoid example we derived above.

Points of Interests

For our Currency Converter functoid we only considered GAC functoid, that should be deployed to GAC, however we have got another option to build a functoid it's called Inline Script Functoid, in this approach you expose your functoid code, that's .NET code, to the mapper and during runtime the Mapper embeds the functoid code into the map, while this has an advantage of being independent on the GAC assembly, but it has disadvantage that you embed the code into the map.

Currency Converter Functoid depends on the Currency Converter Webservice, if any interface changes, which is rare to happen, you should take care about that.

Conclusion

You have learnt how to use standard functoids, and we have gone through an example about consuming Database Lookup functoid, also you have built a GAC Currency Converter custom functoid that's consuming a Currency Converter Webservice.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Kareem Shaker


Kareem Shaker is a .NET Architect , He's been working with VC++ and VB since version 4.0 ; Kareem has been working on design and development of many business applications , And he's now spending most of his time working with .NET Framework 1.x and 2.0 using both VB.NET and C# , Kareem has been giving some technical sessions targeted to .NET technologies, One of the technolgoies that I have passion to is EAI, I spend most of my times working on BizTalk Server 2006, I like to share knowledge and to interact with geeks around, Blogging is one of my hobbies, my blog is http://CairoCafe.Blogspot.com
Occupation: Architect
Location: United Arab Emirates United Arab Emirates

Other popular Microsoft BizTalk Server articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 10 of 10 (Total in Forum: 10) (Refresh)FirstPrevNext
GeneralInline XSLT Call Template with input parametersmemberDennis van Mierlo2:16 21 Apr '08  
QuestionNice articlememberamitparva9:53 30 Apr '07  
AnswerRe: Nice articlememberKareem Shaker21:16 30 Apr '07  
QuestionEnabling option "Configure Functoid Script" with custom functoidmemberpbvs6:47 5 Apr '07  
GeneralVery Good indeed!memberhalzoak0:33 16 Aug '06  
GeneralRe: Very Good indeed!memberKareem Shaker1:54 16 Aug '06  
QuestionHow i can towork with record input parameters in functoids?memberJocano12:08 15 Aug '06  
AnswerRe: How i can towork with record input parameters in functoids?memberKareem Shaker21:47 15 Aug '06  
GeneralGood job!memberMike_V17:17 12 Aug '06  
GeneralRe: Good job!memberKareem Shaker22:24 12 Aug '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 11 Aug 2006
Editor:
Copyright 2006 by Kareem Shaker
Everything else Copyright © CodeProject, 1999-2008
Web17 | Advertise on the Code Project