Microsoft Technologies based on the .NET software framework. Miscellaneous topics that do not fit into specific categories.
If you only need the raw SOAP XML for troubleshooting, the simplest approach is to enable WCF message logging in web.config / app.config. WCF can log messages at the transport and service level before they reach your service operation code. Microsoft documents this under WCF message logging configuration. [learn.microsoft.com]
Example:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\Logs\messages.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
logMalformedMessages="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000000" />
</diagnostics>
</system.serviceModel>
Make sure the C:\Logs folder exists and the application pool / service account has permission to write there.
If you need to log the SOAP XML inside your application code before the service method is called, use IDispatchMessageInspector. Its AfterReceiveRequest method is called after WCF receives the request but before it dispatches the message to the service operation. Microsoft also documents this approach here: How to inspect and modify messages on the service. [learn.microsoft.com]
Example:
using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Xml;
public class RawSoapMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
// WCF Message can only be read once, so create a buffered copy
MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue);
// Copy for logging
Message copy = buffer.CreateMessage();
using (StringWriter sw = new StringWriter())
using (XmlWriter xw = XmlWriter.Create(sw))
{
copy.WriteMessage(xw);
xw.Flush();
string rawSoapXml = sw.ToString();
File.AppendAllText(
@"C:\Logs\IncomingSoap.log",
rawSoapXml + Environment.NewLine);
}
// Recreate the request so WCF can continue processing it
request = buffer.CreateMessage();
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
// Optional: log response here
}
}
Then attach it using a service behavior:
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
public class RawSoapLoggingBehavior : Attribute, IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new RawSoapMessageInspector());
}
}
}
public void AddBindingParameters(
ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
Apply it to your service class:
[RawSoapLoggingBehavior]
public class MyService : IMyService
{
public string MyOperation()
{
return "OK";
}
}
The key point is that you should not directly read the original Message and then continue processing it, because the WCF message body is forward-only. Create a buffered copy, log one copy, and assign another copy back to request.
Also, be careful when logging full SOAP messages in production, because the XML may contain passwords, tokens, personal data, or other sensitive values. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guidance or provide feedback.
Thank you.