BizTalk Server WCF 自定义服务行为





5.00/5 (3投票s)
BizTalk WCF 自定义服务行为,用于在端口级别发送响应(根据输入填充一些值)。
引言
BizTalk 的 WCF 具有强大的功能。 我们可以做很多事情,只需要去发现它们。 由于它还不是很老,很多内容在网上找不到。 但请相信,它远不止我们想象的那么简单。
我只是与您分享其中一项功能。
背景
问题描述:假设您想创建一个 BizTalk 接收位置(WCF Webservice),并且在接收到此端口上的请求后,需要同步发送一个响应(在同一时间内),响应的 XML 类型为某种类型,但需要从**输入消息字段填充响应 XML 字段**。
注意:在不使用 Orchestration 的情况下解决上述问题。
解决方案
我们可以通过创建一个 WCF-自定义服务行为来解决上述问题,而无需使用 Orchestration。
步骤
- 创建一个 BizTalk Server 接收位置,类型为 WCF-CusomIsolated(或者我们可以使用 WCF-Custom,在这种情况下将其托管在 In-Process 宿主中)。
- 添加一个类库项目,并添加三个类。
- CustomTechKundanBTSResponseProviderBehaviorExtensionElement.cs
- CustomTechKundanBTSResponseProviderMessageInspector.cs
- CustomTechKundanBTSResponseProviderServiceBehavior.cs
- 编译并 GAC 部署 DLL。
- 在 32 位和 64 位 machine.config 文件中,都添加以下行到 2.0 和 4.0 machine.config 文件中。
- 转到 WCF-Custom(或 WCF-CustomIsolated)接收位置,在“行为”选项卡上,右键单击并添加扩展。 您可以在列表中看到 CustomTechKundanBTSResponse,添加它,并提供成功和错误响应 XML。
//Start CustomTechKundanBTSResponseProviderBehaviorExtensionElement.cs
using System;
using System.Collections.Generic;using System.Text;
using System.ServiceModel.Configuration;
using System.Configuration;
using System.Xml.Schema;
using System.Xml;
namespace Kundan.Integrations.WCF{
public class CustomTechKundanBTSResponseProviderBehaviorExtensionElement :
BehaviorExtensionElement{public CustomTechKundanBTSResponseProviderBehaviorExtensionElement(){
}
public override Type BehaviorType{
get{return typeof(CustomTechKundanBTSResponseProviderServiceBehavior);}
}
protected override object CreateBehavior(){
return new CustomTechKundanBTSResponseProviderServiceBehavior(SuccesResponse,
ErrorResponse, MaxLengthFaultMessage);}
[ConfigurationProperty("SuccesResponse", DefaultValue = "", IsRequired = false)]
public string SuccesResponse{
get { return (string)base["SuccesResponse"]; }
set { base["SuccesResponse"] = 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; }}
}
}
//End: CustomTechKundanBTSResponseProviderBehaviorExtensionElement.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Xml;
using System.Xml.XPath;
namespace Kundan.Integrations.WCF{
public class CustomTechKundanBTSResponseProviderMessageInspector :
IDispatchMessageInspector{String _succesResponse = null;
String _errorResponse = null;
int? _maxLengthFaultString;
bool _emptyMessage;
XPathDocument Requestdocument = null;
XmlDocument xmldoc = null;
public CustomTechKundanBTSResponseProviderMessageInspector(
String succesResponse, String errorResponse, int? maxLengthFaultString){
_succesResponse = succesResponse;
_errorResponse = errorResponse;
_maxLengthFaultString = maxLengthFaultString;
}
#region IDispatchMessageInspector Members
object IDispatchMessageInspector.AfterReceiveRequest(ref Message request,
IClientChannel channel, InstanceContext instanceContext){
_emptyMessage = request.IsEmpty;
xmldoc =
new XmlDocument();xmldoc.Load(request.GetReaderAtBodyContents());
System.Diagnostics.
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 messagemessage.Headers.CopyHeadersFrom(request.Headers);
message.Properties.CopyProperties(request.Properties);
//assign the new message to the referenced request messagerequest = message;return null;}
void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState){
System.IO.
StringReader stringreader = null;System.Diagnostics.
EventLog.WriteEntry("KundanBTS WCF compo", "Inside Reply");
String sErrorResponse = "";
String sSuccesResponse = "";
if (!_emptyMessage){
if (reply.IsFault){
System.Diagnostics.
EventLog.WriteEntry("KundanBTS WCF compo", "Inside Error");
//create the error message if the property is setif (
// _errorResponse != null && _errorResponse.Length > 0){
if (_errorResponse.Contains("%providerID%")){
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;}
sErrorResponse = _errorResponse;
sErrorResponse = sErrorResponse.Replace(
"%providerID%", strProvider);sErrorResponse = sErrorResponse.Replace(
"%RequesterID%", strRequester);
stringreader =
new System.IO.StringReader(sErrorResponse);
}
else{return;}
}
}
else{
//create the succes message if the property is
//setSystem.Diagnostics.EventLog.WriteEntry("KundanBTS WCF compo", "Inside Success");
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;
}
sSuccesResponse = _succesResponse;
sSuccesResponse = sSuccesResponse.Replace(
"%providerID%", strProvider);sSuccesResponse = sSuccesResponse.Replace(
"%RequesterID%", strRequester);stringreader =
new System.IO.StringReader(sSuccesResponse);
}
XmlTextReader xmlreader = new XmlTextReader(stringreader);
// Create new message Message newMsg = Message.CreateMessage(reply.Version, null, xmlreader);
// Close the original message and return new messagereply.Close();
reply = newMsg;
}
}#endregion}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel.Description;
using System.Xml.Schema;
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
namespace Kundan.Integrations.WCF{
public class CustomTechKundanBTSResponseProviderServiceBehavior :
IServiceBehavior{String _succesResponse = null;
String _errorResponse = null;
int? _maxLengthFaultString;
public CustomTechKundanBTSResponseProviderServiceBehavior(String succesResponse,
String errorResponse, int? maxLengthFaultString){
_succesResponse = succesResponse;
_errorResponse = errorResponse;
_maxLengthFaultString = maxLengthFaultString;
}
public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
System.Collections.ObjectModel.Collection<ServiceEndpoint> 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(_succesResponse,
_errorResponse, _maxLengthFaultString);epDisp.DispatchRuntime.MessageInspectors.Add(inspector);
}
}
}
public void Validate(ServiceDescription serviseDescription, ServiceHostBase serviceHostBase){
}
}
}
<add name="CustomTechKundanBTSResponse"
type="Kundan.Integrations.WCF.CustomTechKundanBTSResponseProviderBehaviorExtensionElement,
Kundan.Integrations.WCF.CustomTechKundanBTSResponse,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=c1a801be9a87ef72" />
重新启动 IIS 和 BizTalk 宿主实例。
现在使用您的应用程序或 SOAPUI 进行测试。