WCF BehaviorExtensions – Re-Write the XML Reply Content from the SOAP Response Envelope

WCF BehaviorExtensions – Re-Write the XML Reply Content from the SOAP Response Envelope

   Log.cs ( Project : Logger ( Class Library ) )
 
   using System;
   using System.Collections.Generic;
   using System.Linq;
   using System.Web;
   using System.ServiceModel.Dispatcher;
   using System.ServiceModel.Description;
   using System.ServiceModel.Channels;
   using System.ServiceModel;
   using System.Collections.ObjectModel;
   using System.Xml;
   using System.Xml.Serialization;
   using System.IO;
   using System.Text;
 
   namespace Logger
   {
      public class Log : IDispatchMessageInspector, IServiceBehavior
      {
 
         // Not Used – Override Function
 
         public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
         {
            return null;
         }
 
         public void BeforeSendReply(ref Message reply, object correlationState)
         {
            if (reply != null && !reply.IsEmpty && reply.State == MessageState.Created)
            {
               reply = TransformMessage(reply);
            }
         }
 
         private Message TransformMessage(Message oldMessage)
         {
 
            // Load the SOAP Message to XMLDocument Object
 
            Message newMessage = null;
 
            MessageBuffer msgbuf = oldMessage.CreateBufferedCopy(int.MaxValue);
 
            Message tmpMessage = msgbuf.CreateMessage();
 
            XmlDictionaryReader xdr = tmpMessage.GetReaderAtBodyContents();
 
            XmlDocument xdoc = new XmlDocument();
 
            xdoc.Load(xdr);
 
            xdr.Close();
 
 
            // Cast the XMLDocument Object to String for Rewritting
 
            String XMLContent = xdoc.OuterXml.<. Do Something on the XML String .>;
 
            xdoc.LoadXml(XMLContent);
 
 
            // Parse the String to XMLDocument Object with XML Standard Format Validation
 
            MemoryStream ms = new MemoryStream();
 
            XmlWriter xw = XmlWriter.Create(ms);
 
            xdoc.Save(xw);
 
            xw.Flush();
 
            xw.Close();
 
            ms.Position = 0;
 
            XmlReader xr = XmlReader.Create(ms);
 
 
            // Encapsulate the XMLDocument Object on SOAP Response Envelope
 
            newMessage = Message.CreateMessage(oldMessage.Version, null, xr);
 
            newMessage.Headers.CopyHeadersFrom(oldMessage);
 
            newMessage.Properties.CopyProperties(oldMessage.Properties);
 
 
            return newMessage;
         }
 
         // Not Used – Override Function
 
         public void AddBindingParameters(
            ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters
         )
         {
         }
 
         public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
         {
            for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
            {
               ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
 
               if (channelDispatcher != null)
               {
                  foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
                  {
                     Log inspector = new Log();
                     endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
                  }
               }
            }
         }
 
         // Not Used – Override Function
 
         public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
         {
         }
 
      }
   }
 
   WcfMessageLoggerExtension.cs ( Project : Logger ( Class Library ) )
 
   using System;
   using System.Collections.Generic;
   using System.Linq;
   using System.Text;
   using System.Threading.Tasks;
   using System.ServiceModel.Configuration;
 
   namespace Logger
   {
      public class WcfMessageLoggerExtension : BehaviorExtensionElement
      {
         protected override object CreateBehavior()
         {
            return new Log();
         }
 
         public override Type BehaviorType
         {
            get
            {
               return typeof(Log);
            }
         }
      }
   }
 
   web.conf ( Project : WCFSOAP ( WCF Service Application ) )
 
   <?xml version="1.0"?>
 
   <configuration>
 
      <appSettings>
 
         … …
 
      </appSettings>
 
      <system.web>
         <compilation debug="true" targetFramework="4.5" />
         <httpRuntime targetFramework="4.5" />
      </system.web>
 
      <system.serviceModel>
 
         <extensions>
            <behaviorExtensions>
               <add name="WcfMessageLogger"
                        type="Logger.WcfMessageLoggerExtension, Logger, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
            </behaviorExtensions>
         </extensions>

 
         <behaviors>
 
            <serviceBehaviors>
 
               <behavior>
 
                  … …
 
                  <WcfMessageLogger />
 
               </behavior>
 
            </serviceBehaviors>
 
         </behaviors>
 
         … …
 
      </system.serviceModel>
 
      … …
 
   </configuration>
 

 
Remarks :
It is not a Best Practice for .net SOAP Server & .net SOAP Client.
This Customized SOAP Function is for the non .net SOAP Client to Parse the XML SOAP Response.