Я хочу реализовать логирование SOAP для моего приложения C#.
И у меня проблема с ApplyClientBehavior, он не вызывается.
Если есть идеи, как это улучшить, поделитесь со мной, пожалуйста.
Вот код, который у меня есть сейчас:
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) {
}
}
}