Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C#

BizTalk Server WCF Custom Service Behaviour

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
20 Sep 2012CPOL1 min read 30.2K   7   5
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)


Written By
Architect iGATE Global technology solutions
India India
I am BizTalk Server Technology Specialist.I have more than 8+ years of experience on BizTalk Server.I have worked on almost all the versions of BizTalk server 2004/2006/2006R2/2009/2010/2013.

I played multiple roles (Developer/Tech.Lead/Integration Architect) on Several BizTalk Projects.

I have keen interest in developing BizTalk-Integration solutions using SOA,WCF,ESB,EDI, Host Integration Server,Windows Azure BizTalk Services.

Comments and Discussions

 
QuestionAfterReceiveRequest Service call bypass Pin
Amrit Sidhu25-Mar-15 14:18
Amrit Sidhu25-Mar-15 14:18 
QuestionWCF Custom Service in a Send location Pin
PabitraDash20-Jul-13 3:25
PabitraDash20-Jul-13 3:25 
AnswerRe: WCF Custom Service in a Send location Pin
KundanKarma23-Sep-13 20:49
KundanKarma23-Sep-13 20:49 
GeneralMy vote of 5 Pin
Pritpal Singh Bumrah26-Sep-12 9:23
Pritpal Singh Bumrah26-Sep-12 9:23 
GeneralRe: My vote of 5 Pin
KundanKarma26-Sep-12 23:13
KundanKarma26-Sep-12 23:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.