Click here to Skip to main content
Click here to Skip to main content
Go to top

BizTalk Server WCF Custom Service Behaviour

, 20 Sep 2012
Rate this:
Please Sign up or sign in to vote.
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. //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. 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. 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. <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)

Share

About the Author

KundanKarma
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.
Follow on   Google+   LinkedIn

Comments and Discussions

 
QuestionWCF Custom Service in a Send location PinmemberPabitraDash20-Jul-13 3:25 
AnswerRe: WCF Custom Service in a Send location PinmemberKundanKarma23-Sep-13 20:49 
GeneralMy vote of 5 PinmemberPritpal Singh Bumrah26-Sep-12 9:23 
GeneralRe: My vote of 5 PinmemberKundanKarma26-Sep-12 23:13 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140921.1 | Last Updated 20 Sep 2012
Article Copyright 2012 by KundanKarma
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid