WCF service client: How do I debug the response parsing - wcf

I am building a web service client to interact with a (java-based) remote web service, out of my control. I can call the web service operation, and can tell by packet-sniffing that the service is responding with populated data. However, by the time that response makes it into the client code, the response is only a shell, with all the data null.
I suspect that an error is occurring in the web service "plumbing" that is causing the data to be silently dropped or ignored, but I can't find a way to enable debugging (or even logs or error messages?) during the receipt of the response before it hits my client code.
My App.config has Message Logging enabled, but only outgoing messages are being logged:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\messages.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000"/>
</diagnostics>
</system.serviceModel>
I really want to set a breakpoint during the actual parsing of the response message, but having the Message Logger actually log the response may also help a bit.
I've also configured a custom MessageEncoder which was necessary to work around a bug in the remote service's parser. I can add breakpoints to the ReadMessage methods on that MessageEncoder, and can see that the data is still there at that point. However, the next step jumps back into the client code, and the Response object is empty -- no warnings or messages. Is there any way to see what's going on in between?
So, I guess this ends up being a two-part question:
How/Where can I set a breakpoint to observe the SOAP message getting
processed, after the MessageEncoder, but before it is sent to the client code?
What's wrong with my logging config that only outgoing
messages are logged?

Here is how you can get the response tracing to work for you:
1. Configuration
<system.diagnostics>
<sharedListeners>
<add name="sharedListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\LogFiles\messages.svclog" />
</sharedListeners>
<sources>
<source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" >
<listeners>
<add name="sharedListener" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
<listeners>
<add name="sharedListener" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics performanceCounters="All" wmiProviderEnabled="True">
<messageLogging
logEntireMessage="True"
logMalformedMessages="True"
logMessagesAtServiceLevel="True"
logMessagesAtTransportLevel="True"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="30000"/>
</diagnostics>
</system.serviceModel>
This goes in your app.config / web.config under the configuration node.
2. Locating the Response
A quick validation to see that you actually receive service responses from the remote service is to open up the log file as an xml file in Visual studio and do a search for
Source="TransportReceive"
you should be able to see what the remote service has responded with within this MessageLogTraceRecord node.
3. Tooling
The recommended tool for viewing these messages is SvcTraceViewer.exe
You should be able to find this in either:
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\x64
or
C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin
If you do not have this tool, you can find it in the Windows Sdk

Related

Can I use WCF tracing without config file?

In my WCF application, I have not used a config file in both client and server. I have created the address, binding and contract in code and used them to host the service and this is working fine. Now i want to add WCF tracing and I am not finding a way to add the tracing through code like below, where a config file is used:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messagelistener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="d:\logs\myMessages.svclog"></add>
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true"
logMessagesAtServiceLevel="false"
logMessagesAtTransportLevel="false"
logMalformedMessages="true"
maxMessagesToLog="5000"
maxSizeOfMessageToLog="2000">
</messageLogging>
</diagnostics>
</system.serviceModel>
Please refer to the official document about implementing this feature in code.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/tracing-and-message-logging
https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/trace-listeners
https://learn.microsoft.com/en-us/dotnet/framework/wcf/diagnostics/configuring-message-logging
FileStream fs = new FileStream(#"C:\1.mylog.svclog", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
System.Diagnostics.Trace.Listeners.Clear();
System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.XmlWriterTraceListener(fs));
Besides, as far as I know, we can’t configure the WCF Message Logging in code. It only could be configured in the WebConfig.
https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/messagelogging
Feel free to let me know if there is anything I can help with.

WCF XmlWriterTraceListener does not log message

I've got an IIS application that host SOAP endpoints that I am trying to add logging to for debugging purposes. The calls are executed and processed, but the message contents are in question. I need to verify the contents before any processing is done.
I've located the web.config file and added logging as follows
<system.serviceModel>
<diagnostics performanceCounters="ServiceOnly">
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="false"
maxMessagesToLog="300000"
maxSizeOfMessageToLog="65535000"/>
</diagnostics>
</system.serviceModel>
And
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
<listeners>
<add name="MyCustomLogging"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\Temp\MyCustomLogging.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
The logging works fine when I test it with smaller messages (< 2 KB) - screenshot from Service Trace Viewer
But when the real integration is triggered, the messages sent across are much lager, around 250KB each. And those are not logged. I just get an empty MessageLogTraceRecord element in my trace - screenshot from Service Trace Viewer
The size might not be the real problem, but that is the only thing I can think of. The real messages are sent by a third party and I don't have access to their system, nor do I know what they are using to send the messages. But the messages are successfully received by our application and processed, so they do make it over.
Any pointers/thoughts would be appreciated!
Found the answer.
I needed to add
<endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true" />
in the diagnostics tag, underneath the messageLogging tag, like this
<diagnostics performanceCounters="ServiceOnly">
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="300000"
maxSizeOfMessageToLog="65535000"/>
<endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true" />
</diagnostics>

How to log incoming and outgoing XML from WCF requests

I have a basic WCF hosted in a console app, and a basic console WCF client. How do you look at the requests sent between the two apps (over localhost)?
Should I use something like 'Wireshark' or would it be possible to log out the incoming and outgoing response objects in visual Studio?
I'm already creating an log.svclog file by the system.diagnostics directive in the App.config file, but can't find the actual request and response xml:
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\log\log.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
Which I got from Stack Overflow (I can't remember where)
You need to configure message logging, which is separate from just WCF tracing, which is what you have configured above. See https://msdn.microsoft.com/en-us/library/ms730064(v=vs.110).aspx.

WCF Tracing switchvalue is Off yet there is still a trace output being generated

After having turned on WCF Tracing to assist with finding a problem, I now wish to turn off tracing. So I have changed my config file to this...
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Off" >
<!-- Information,ActivityTracing-->
<listeners>
<add name="xmlTraceListener" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Off" >
<listeners>
<add name="xmlTraceListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xmlTraceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\WCFLogs\DataPortalTrace.svclog" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
Yet there is still trace output being send to the indicated output file. Why is that? What am I missing?
switchValue="Off" will only control System.ServiceModel. It does not control the System.ServiceModel.MessageLogging
As of my knowledge you can control via maxMessagesToLog="0" – you might have already <diagnostics> tag under <system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="0"
/>
</diagnostics>
.NET framework for Configuring Message Logging
The logging level, as well as the additional options, are discussed in the Logging Level and Options section.
The switchValue attribute of a source is only valid for tracing. If you specify a switchValue attribute for the System.ServiceModel.MessageLogging trace source as follows, it has no effect.
Copy
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
If you want to disable the trace source, you should use the logMessagesAtServiceLevel, logMalformedMessages, and logMessagesAtTransportLevel attributes of the messageLogging element instead. You should set all these attributes to false. This can be done by using the configuration file in the previous code example, through the Configuration Editor UI interface, or using WMI. For more information about the Configuration Editor tool, see Configuration Editor Tool (SvcConfigEditor.exe). For more information about WMI, see Using Windows Management Instrumentation for Diagnostics.

Trace all the calls (+ their stack) made to a WCF service

I have a WCF Service which is currently in Production. The code performance are not where we would like them to be and we are unable to reproduce in our Staging environment.
I was wondering if it is possible to log every single method call made to the service and by the service. Essentially I would like a sequential list of all the calls and time stamps (our code isn't multi-threaded).
Is there a way to achieve that without having to instrument the binaries. Is there a level of tracing under the system.diagnostic node in the web.config that we could change?
Have you configured tracing in your configuration file? This is a good article on the subject.
Here is a sample configuration you can use and modify for your needs:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="ServiceModel"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\ServiceModel.svclog" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="MessageLogging"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\MessageLogging.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="True"
logMalformedMessages="False"
logMessagesAtServiceLevel="True"
logMessagesAtTransportLevel="False"
maxMessagesToLog="10000"
maxSizeOfMessageToLog="10000" />
</diagnostics>
</system.serviceModel>
Use the Service Trace Viewer Tool (SvcTraceViewer.exe) to view the resulting logs.
Check WCF Tracing and optionally also WCF message logging and use SvcTraceViewer to check collected data - you can alternatively build your trace listener for logging traces for example to database. WCF also provides performance counters.