0

*We are currently seeking to enhance our C# application's diagnostic capabilities through the implementation of comprehensive SOAP logging. During this process, we have encountered a challenge concerning the ApplyClientBehavior method, which is not being invoked as expected.

This issue is impeding our ability to effectively monitor and troubleshoot SOAP communication, potentially impacting service reliability and response times. *

=======

I want to implement SOAP logging for my c# application. And I have problem with ApplyClientBehavior, it was not called. If any ideas how to improve that, share with me, please. here is a code that I have now :

using System;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Xml;

public class SoapLoggingInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        try
        {
            LogMessage(request, "Outgoing Request");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error logging outgoing request: {ex.Message}");
        }
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        try
        {
            LogMessage(reply, "Incoming Response");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error logging incoming response: {ex.Message}");
        }
    }

    private void LogMessage(Message message, string messageType)
    {
        // Create a copy of the message to read without consuming it
        MessageBuffer buffer = message.CreateBufferedCopy(Int32.MaxValue);
        Message messageCopy = buffer.CreateMessage();

        // Convert message to readable string
        string messageStr = MessageToString(messageCopy);

        // Log the message to console
        Console.WriteLine($"---{messageType} at {DateTime.Now}---");
        Console.WriteLine(messageStr);
        Console.WriteLine("---End of Message---\n");

        // Restore the original message
        message = buffer.CreateMessage();
    }

    private string MessageToString(Message message)
    {
        // Create a XML writer to capture the message
        using (var stream = new MemoryStream())
        {
            using (var writer = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8))
            {
                message.WriteMessage(writer);
                writer.Flush();
            }

            // Convert stream to string
            stream.Position = 0;
            using (var reader = new StreamReader(stream))
            {
                return reader.ReadToEnd();
            }
        }
    }
}

public static class SoapLoggingExtensions
{
    public static void EnableSoapLogging<TChannel>(this ClientBase<TChannel> client)
        where TChannel : class
    {
        // Remove any existing inspector of this type first
        //var existingInspectors = client.Endpoint.EndpointBehaviors
        //    .OfType<IEndpointBehavior>()
        //    .ToList();

        //foreach (var existingBehavior in existingInspectors)
        //{
        //    client.Endpoint.EndpointBehaviors.Remove(existingBehavior);
        //}

        //// Create and add new logging behavior
        //client.Endpoint.EndpointBehaviors.Add(new SoapLoggingEndpointBehavior());

        client.ChannelFactory.Endpoint.EndpointBehaviors.Add(new SoapLoggingEndpointBehavior());
        
    }

    private class SoapLoggingEndpointBehavior : IEndpointBehavior
    {
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            // Add the message inspector
            clientRuntime.ClientMessageInspectors.Add(new SoapLoggingInspector());
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { 
        }
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { 
        }
        public void Validate(ServiceEndpoint endpoint) { 
        }
    }
}
2
  • In WCF, endpoint behavior is used when ChannelFactory creates a runtime channel. If you add custom behavior too late -- after the channel is created -- the ApplyClientBehavior method won't run. Commented Mar 28 at 10:11
  • Thanks! Looks like that it is close to my case , but I still do not understand how to implement that right. I generated SOAP WCF client via stardart visual studio wizard and I want to log all communication messages now to console. How I can do that ? any code sample ? Commented Mar 28 at 14:32

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.