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.