尽管 BizTalk Server 提供许多Functoid以支持一系列不同的操作,但仍可能会遇到需要其他方法的情况。《BizTalk开发系列 Map扩展开发》介绍了通过使用自定义 XSLT,脚本 Functoid等方法来扩展。这里要介绍的是通过自定义 functoid 的方法扩展。
每个自定义Functoid为从Microsoft.BizTalk.BaseFunctoids派生的类的 .NET 程序集。一个程序集可包含多个自定义 functoid。下图的Format Date功能块是自定义开发的Functoid,功能是将输入参数1的字符串按参数2的格式输出。部署之后添加到工具箱。
微软提供了相关使用自定义Functoid的场景:
- 您对使用只能通过专用旧式 API 访问的数据的字符代码字段应用特殊的验证和转换规则。
- 您需要使用自定义业务逻辑和密钥管理来加密或解密字段。
- 您需要从部分消息生成哈希代码以用于其他应用程序。
- 财务要求传输到他们部门的消息包含有关每种产品类型销售总额的摘要信息。
- 您希望通过合并一些相关步骤、使用其他方法或使用新的类库来降低映射的复杂性。
- 多个映射在脚本 functoid 中使用相同的脚本代码。
- 您需要将操作失败写入事件日志。
开发自定义Functoid有以下几个类别:
- 自定义引用 Functoid
自定义引用的 Functoid 不会将内联的实现代码复制到映射中。实际上,它将对程序集、类和方法的引用放置在与生成的样式表相关联的扩展对象文件中,并在运行时对其进行调用。
- 自定义内联 Functoid
自定义内联 functoid 通过将实现代码直接复制到映射中提供功能,而不像自定义引用的 functoid 通过引用程序集、类和方法名称来提供功能。
- 自定义累计 Functoid
自定义累计 functoid 可以对在一个实例消息中多次出现的值执行累计操作。
使用内联代码可直接将自定义 functoid 集成到解决方案中,也可以通过引用部署在全局程序集缓存中的类库的方法来间接集成。这两种类型的集成都依赖于 BizTalk.BaseFunctoid 类并遵循同样一组通用步骤:
- 使用您选择的 .NET 语言创建新的类库项目。
- 使用强名称实用程序 sn.exe 创建密钥文件并将其指定给项目。
- 添加对 Microsoft.BizTalk.BaseFunctoids.dll 的引用。此程序集包含 BaseFunctoid 基类。
- 创建资源文件并将其添加到项目中。为 functoid 名称、工具提示和说明添加字符串资源。添加一个 16x16 像素的图像资源,在映射设计器面板上代表该 functoid。
- 实现 functoid 类,方法是从 BaseFunctoid 派生该类,在构造函数中建立基本参数,然后编写 functoid 方法和所有支持方法。该程序集可包含多个自定义 functoid。
- 部署该程序集并确保可从工具箱面板访问新 functoid。
Format Date Functoid代码
using System; using Microsoft.BizTalk.BaseFunctoids; using System.Reflection; using System.Text; using System.Collections; using System.Globalization; namespace Quicklearn.CN.BTS.CustomerFunctoids { public class FormatDate : BaseFunctoid { public FormatDate() : base() { //Functoid的ID号.尚未用过的大于6000的值. this.ID = 88888; //资源文件 SetupResourceAssembly("Quicklearn.CN.BTS.CustomerFunctoids.Resource", Assembly.GetExecutingAssembly()); //Functoid的名称,描述,说明,图像 SetName("QUICKLEARN_CN_FORMATDATE_NAME"); SetTooltip("QUICKLEARN_CN_FORMATDATE_TOOLTIP"); SetDescription("QUICKLEARN_CN_FORMATDATE_DESCRIPTION"); SetBitmap("QUICKLEARN_CN_FORMATDATE_BITMAP"); //this.HasVariableInputs = true; //参数个数是否不确定 this.SetMinParams(2);//最小参数 this.SetMaxParams(2);//最大参数 SetExternalFunctionName(GetType().Assembly.FullName, "Quicklearn.CN.BTS.CustomerFunctoids.Resource", "Format"); this.Category = FunctoidCategory.String; //分类 this.OutputConnectionType = ConnectionType.All;//输出类型 //设置支持的脚本格式(内联型Functoid需要设置此项). AddScriptTypeSupport(ScriptType.CSharp); //内联型的脚本,代码将会被拷贝到XSLT文件中.方便调试. SetScriptBuffer(ScriptType.CSharp, InitFormat(), 0); AddInputConnectionType(ConnectionType.All); //第一个参数类型 AddInputConnectionType(ConnectionType.All); //第二个参数类型 } public string Format(string paramDate,string paramExpress) { string responseDate = paramDate; try { DateTime strDate = Convert.ToDateTime(paramDate); responseDate = strDate.ToString(paramExpress); } catch { } return responseDate; } //将方法代码映射到XSLT。 private string InitFormat() { StringBuilder builder = new StringBuilder(); builder.Append("public string Format(string paramDate,string paramExpress)\n"); builder.Append("{\n"); builder.Append(" string responseDate = paramDate;\n"); builder.Append(" try\n"); builder.Append("{\n"); builder.Append(" DateTime strDate = Convert.ToDateTime(paramDate);\n"); builder.Append(" responseDate = strDate.ToString(paramExpress);\n"); builder.Append("}\n"); builder.Append("catch { }\n"); builder.Append("return responseDate;\n"); builder.Append("}\n"); return builder.ToString(); } } }
测试
自定义Functoid
的测试工作非常不方便,简化该过程可以先使用自定义内联脚本或外部程序集的方式先将程序调整完好。另外对于内联Functoid可以将Map生成XSLT
进行详细调试。以下是通过验证Map生成的XSLT内容,内联型的Functoid已经将方法代码拷贝到XSLT中。