Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

BizTalk Server WCF Custom Service Behaviour

5.00/5 (3 votes)
20 Sep 2012CPOL1 min read 31.1K  
BizTalk WCF Custom Service Behaviour for sending Response back (filling some values from input) at port level.

Introduction

WCF with BizTalk comes with great features. There are a lot of things we can do this, we just need to discover them. As it is not too old, a lot of things can't be found on the web. But believe me it is much more than what we think.

I am just sharing one of the features with you.

Background

Problem statement: Suppose you want to create a BizTalk receive location (of WCF Webservice), and once you receive a request on this port, you need to send a Response back (with-in same time synchronously) with some kind of XML type but populating some of the response XML fields from Input message fields.

Note: Solve the above problem without using an Orchestration.

Solution

We can solve the above problem without using an Orchestration, by creating a WCF-Custom Service Behaviour.

Steps

  1. Create a BizTalk Server Receive location of WCF-CusomIsolated (or we can use WCF-Custom, host it on In-Process host in this case).
  2. Add a Class Library project and add three classes.
    1. CustomTechKundanBTSResponseProviderBehaviorExtensionElement.cs
    2. C#
      //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
    3. CustomTechKundanBTSResponseProviderMessageInspector.cs
    4. C#
      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}
      }
    5. CustomTechKundanBTSResponseProviderServiceBehavior.cs
    6. C#
      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){
      }
      }
      }
  3. Compile and GAC the DLL.
  4. Add below line to 2.0 and 4.0 machine.config both at 32 bit and 64 bit machine.config files.
  5. XML
    <add name="CustomTechKundanBTSResponse" 
      type="Kundan.Integrations.WCF.CustomTechKundanBTSResponseProviderBehaviorExtensionElement, 
            Kundan.Integrations.WCF.CustomTechKundanBTSResponse, 
            Version=1.0.0.0, Culture=neutral, PublicKeyToken=c1a801be9a87ef72" />

    Re-start IIS and BizTalk Host instances.

  6. Go to WCF-Custom (or WCF-CustomIsolated) receive location and on Behaviour tab, right click and Add-Extension. You can see CustomTechKundanBTSResponse in the list, add it, and provide Success and Fault Response XMLs.

Now test it with your application or using SOAPUI.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)