BizTalk WCF 自定义响应提供者行为扩展

在BizTalk Server中,经常需要创建接收位置来处理外部的Web服务请求。本文将介绍如何在不使用Orchestration的情况下,通过创建一个WCF-Custom服务行为来实现对请求的同步响应。

在某些情况下,可能需要在BizTalkServer中创建一个WCFWebservice类型的接收位置,并在接收到请求后立即同步返回一个XML类型的响应。这个响应需要根据输入消息中的字段来填充响应XML中的某些字段。

问题陈述

假设需要创建一个BizTalkWCFWebservice接收位置,一旦在这个端口上接收到请求,就需要立即同步返回一个响应,并且这个响应是一个XML类型,但是需要从输入消息的字段中填充响应XML的一些字段。

解决方案

可以通过创建一个WCF-Custom服务行为来解决上述问题,而不需要使用Orchestration。以下是实现步骤:

首先,需要在BizTalkServer中创建一个WCF-CustomIsolated类型的接收位置。如果需要,也可以使用WCF-Custom,并将其托管在进程内主机上。

接下来,需要添加一个类库项目,并在其中添加以下三个类:

  • CustomTechKundanBTSResponseProviderBehaviorExtensionElement.cs
  • CustomTechKundanBTSResponseProviderMessageInspector.cs
  • CustomTechKundanBTSResponseProviderServiceBehavior.cs

这个类是自定义行为扩展元素,它允许在配置文件中定义成功和错误响应的XML。

public class CustomTechKundanBTSResponseProviderBehaviorExtensionElement : BehaviorExtensionElement { public CustomTechKundanBTSResponseProviderBehaviorExtensionElement() { } public override Type BehaviorType { get { return typeof(CustomTechKundanBTSResponseProviderServiceBehavior); } } protected override object CreateBehavior() { return new CustomTechKundanBTSResponseProviderServiceBehavior(SuccessResponse, ErrorResponse, MaxLengthFaultMessage); } [ConfigurationProperty("SuccessResponse", DefaultValue = "", IsRequired = false)] public string SuccessResponse { get { return (string)base["SuccessResponse"]; } set { base["SuccessResponse"] = value; } } [ConfigurationProperty("ErrorResponse", DefaultValue = "", IsRequired = false)] public string ErrorResponse { get { return (string)base["ErrorResponse"]; } set { base["ErrorResponse"] = value; } } [ConfigurationProperty("MaxLengthFaultMessage", DefaultValue = "", IsRequired = false)] public int? MaxLengthFaultMessage { get { return (int?)base["MaxLengthFaultMessage"]; } set { base["MaxLengthFaultMessage"] = value; } } }

这个类实现了IDispatchMessageInspector接口,用于在收到请求后创建响应消息。

public class CustomTechKundanBTSResponseProviderMessageInspector : IDispatchMessageInspector { private string _successResponse = null; private string _errorResponse = null; private int? _maxLengthFaultString; private bool _emptyMessage; public CustomTechKundanBTSResponseProviderMessageInspector(string successResponse, string errorResponse, int? maxLengthFaultString) { _successResponse = successResponse; _errorResponse = errorResponse; _maxLengthFaultString = maxLengthFaultString; } object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { _emptyMessage = request.IsEmpty; XmlDocument xmldoc = new XmlDocument(); xmldoc.Load(request.GetReaderAtBodyContents()); // Log the request message EventLog.WriteEntry("KundanBTS WCF compo", xmldoc.InnerXml); Message message = Message.CreateMessage(request.Version, null, new XmlNodeReader(xmldoc)); // Copy back the original headers and properties to the new message message.Headers.CopyHeadersFrom(request.Headers); message.Properties.CopyProperties(request.Properties); // Assign the new message to the referenced request message request = message; return null; } void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState) { if (!_emptyMessage) { if (reply.IsFault) { // Create the error message if the property is set if (_errorResponse != null && _errorResponse.Length > 0) { string strProvider = null; string strRequester = null; XPathNavigator navigator = xmldoc.CreateNavigator(); XPathNodeIterator Providernode = navigator.Select("//*[local-name()='providerID']"); XPathNodeIterator Requesternode = navigator.Select("//*[local-name()='RequesterD']"); while (Providernode.MoveNext()) { strProvider = Providernode.Current.Value; } while (Requesternode.MoveNext()) { strRequester = "KundanBTS_" + Requesternode.Current.Value; } string sErrorResponse = _errorResponse; sErrorResponse = sErrorResponse.Replace("%providerID%", strProvider); sErrorResponse = sErrorResponse.Replace("%RequesterID%", strRequester); StringReader stringreader = new System.IO.StringReader(sErrorResponse); XmlTextReader xmlreader = new XmlTextReader(stringreader); Message newMsg = Message.CreateMessage(reply.Version, null, xmlreader); reply.Close(); reply = newMsg; } } else { // Create the success message if the property is set string strProvider = null; string strRequester = null; XPathNavigator navigator = xmldoc.CreateNavigator(); XPathNodeIterator Providernode = navigator.Select("//*[local-name()='providerID']"); XPathNodeIterator Requesternode = navigator.Select("//*[local-name()='RequesterID']"); while (Providernode.MoveNext()) { strProvider = Providernode.Current.Value; } while (Requesternode.MoveNext()) { strRequester = Requesternode.Current.Value; } string sSuccessResponse = _successResponse; sSuccessResponse = sSuccessResponse.Replace("%providerID%", strProvider); sSuccessResponse = sSuccessResponse.Replace("%RequesterID%", strRequester); StringReader stringreader = new System.IO.StringReader(sSuccessResponse); XmlTextReader xmlreader = new XmlTextReader(stringreader); Message newMsg = Message.CreateMessage(reply.Version, null, xmlreader); reply.Close(); reply = newMsg; } } } }

这个类实现了IServiceBehavior接口,用于在服务行为中添加消息检查器。

public class CustomTechKundanBTSResponseProviderServiceBehavior : IServiceBehavior { private string _successResponse = null; private string _errorResponse = null; private int? _maxLengthFaultString; public CustomTechKundanBTSResponseProviderServiceBehavior(string successResponse, string errorResponse, int? maxLengthFaultString) { _successResponse = successResponse; _errorResponse = errorResponse; _maxLengthFaultString = maxLengthFaultString; } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { CustomTechKundanBTSResponseProviderMessageInspector inspector = null; foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers) { foreach (EndpointDispatcher epDisp in chDisp.Endpoints) { inspector = new CustomTechKundanBTSResponseProviderMessageInspector(_successResponse, _errorResponse, _maxLengthFaultString); epDisp.DispatchRuntime.MessageInspectors.Add(inspector); } } } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } }

编译上述类库项目,并将其添加到全局程序集缓存(GAC)中。

在32位和64位的machine.config文件中添加以下配置:

<add name="CustomTechKundanBTSResponse" type="Kundan.Integrations.WCF.CustomTechKundanBTSResponseProviderBehaviorExtensionElement, Kundan.Integrations.WCF.CustomTechKundanBTSResponse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c1a801be9a87ef72" />

更新配置后,需要重启IIS和BizTalk Host实例。

在WCF-Custom(或WCF-CustomIsolated)接收位置的行为选项卡上,右键单击并添加扩展。可以看到CustomTechKundanBTSResponse在列表中,添加它,并提供成功和错误响应XML。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485