I'm receiving an "Unrecognized message version" error when calling a home-grown WCF service. This service sits in the DMZ behind an F5 load balancer. The F5 manages SSL certs then forwards the message onto the server over HTTP (not HTTPS). The same service deployed on an internal server that does not route through the F5 works fine.
I want to inspect the version of the messages along the way. The server stack trace looks as though IIS is handing off to .NET code within the guts of the WCF framework then blowing up before it forwards the message to my code.
I've been playing around with Fiddler on the client side and the IIS logging on the server but can't seem to find message details that would lead me anywhere. I've also configured the service trace log (config below) but am seeing no results added. Any other suggestions either of tools, cause of the error or what I may not be understanding of what the tools are showing me?
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "c:\Temp\Traces.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
UPDATE - Core issue solved
I've since found the specific issue I was having was based on the F5 load balancer redirecting back to itself as well as onto the server as expected. I think it may still be useful to know more about how to track the state of a request along the way.
Here are a couple of things to check:
Does the wcf process have write access to the c:\temp directory? (ProcessMonitor can be really useful for verifying this sort of thing: http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
It sounds like it could be a serialization issue, maybe try adding a listener on System.Runtime.Serialization as described here: http://msdn.microsoft.com/en-us/library/ms733025.aspx
Related
Receiving this error when trying to work with the queue:
Unexpected error occured: The communication object, System.ServiceModel.ServiceHost, cannot be used for communication because it is in the Faulted state.
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
How to overcome it?
Update: answer to my solution posted at the end
This problem is due to access rights. Start Visual Studio with administrative rights and the problem will be resolved.
To start Visual Studio with admin rights right click the Visual Studio icon and select "Run As Administrator".
Update: In my case what helped was:
1) enabling trace logs: http://msdn.microsoft.com/en-us/library/ms732023.aspx
2) in the trace log it wrote this:
Binding validation failed because the binding's ExactlyOnce property is set to true while the destination queue is non-transactional. The service host cannot be opened. Resolve this conflict by setting the ExactlyOnce property to false or creating a transactional queue for this binding.
The answer says it all. Created a transactional queue - everything works :) hope it helps people :)
close your solution, Now follow these steps:
1. Right click on the visual studio.
2. Click on Run as Administrator.
3. Now open your solution.
4. Try running it, your problem will be resolved.
From my experience, once a endpoint is in a faulted state, it will not recover on its own and needs to be restarted. There's no way to make that happen from the client side. The host must do it.
On the host side, you can check for a faulted state using code like this:
While True
'broken connection case
If objServiceHost(ii).State <> CommunicationState.Opened Then
Throw New Exception("SynchronizationWS Service Host failed.")
Exit While
End If
Next
Threading.Thread.Sleep(c_SleepTime) 'sleep 1 second before going trying next
End While
We have a higher level program that monitors the heartbeat of our web service (which runs within a windows service) and if the higher level program finds that the heartbeat has stopped, it will recycle the windows service, restarting the WCF web service.
For me it's because the port was already used by another process, I changed the port and the service worked as usual. I knew this by following the trace logs, just follow steps here: https://learn.microsoft.com/en-us/dotnet/framework/wcf/service-trace-viewer-tool-svctraceviewer-exe
The recap:
add this section to the web.config or app.config file:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "SdrConfigExample.e2e" />
</listeners>
</source>
</sources>
</system.diagnostics>
run the WCF service to reproduce the error.
open SvcTraceViewer.exe tool, I found it in :
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin. It will open the Microsoft Service Trace Viewer window.
Navigate to the log file (File> Open) named "SdrConfigExample.e2e" which was specified in the XML config above, and is located in the root directory. This will list the errors in more detail and you can find the cause of the exception.
*Tip: You can easily and quickly find files on your computer using everything tool.
I need to catch log4net exceptions (its own exceptions not app exceptions logged by it). I wish there's a way of doing it this way:
Try
_logger.Info(response)
Catch ex As Exception
Excepciones.HandleException(ex, "PolicyCore")
End Try
I have this code implemented and there's no errors in compilation but i force log4net to have an error (pointing to a non existing database in the config file) and nothing is threw.
I've tried the listener aproach:
<appSettings>
<add key="log4net.Internal.Debug" value="true" />
</appSettings>
<system.diagnostics>
<trace autoflush="true" indentsize="4" >
<listeners>
<add name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\\temp\\log4net.txt" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
and it's writing the errors to log4net.txt, the forced ones i mean.
This last aproach has a couple of drawbacks: it won't append every error to the file, if the error is the same it doesn't write it, i can't get the listener to write every error to that file, only one (I don't know how to fully configure the trace listener, it might be that). Thus it won't append the date and hour to every line wich is a necesity for me. Finally i can't give structure to it (xml).
Even if the listener work i need to use the try/catch aproach, since i'm using ExceptionHandling from Enterprise library to log the errors in my app.
Anyone who has faced the problem and/or has a solution?
Log4net is designed not to throw any exceptions. This seems to be a good idea because it would be very bad indeed if your application fails because it cannot log. So if you need to log certain messages and need to be sure that this worked, then you should not use a log framework, but rather implement this as part of your "business logic".
You mention that an exception is logged only once. I think that is not true: Log4net usually disables appenders that do not work and thus there is only one exception. The AdoNetAppender for instance can be configured to re-connect to the database in case of a failure in which case you would see the same exception multiple times.
I have deployed a few WCF services to a server via a web setup project
they are being hosted in an IIS Application, which appears to be running fine.
However when i try to navigate to the wsdl, nothing is found.
I am trying to set up diagnostics logging, to get some information.
I have followed the advice from here: wcf trying to set up tracing to debug, not writing to log file
Also, I have tried what is in the referenced MSDN documentation: under "Recommended Settings for Deployment or Debugging" .. my web.config has that identical configuration. But no log file is being created.
Nothing useful in the event viewer.
Any ideas?
Could be a permissions issue; IIRC those don't always turn up in the event log. Ensure the user IIS runs under has write permissions to the log file path.
This is typically the diagnostic config I use. Seems to work for me.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel"
switchValue="Verbose">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="D:\wcfLog.svcLog" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
If you are not getting any output it may be because your service is not starting correctly. The ServiceHost must be up for diagnostics to output anything. With IIS even though your site is running it does not mean that the ServiceHost started correctly. It's usually a config issue. I'm not a web guy but doesn't IIS write to EventViewer if there is an unhandled exception in the website?
Also, you could try creating a custom ServiceHostFactory. That way your code controls the ServiceHost creation and you can trap any exceptions and log them on your own.
Creating a custom ServiceHost in IIS -> LINK
This is an old question but for the benefit of anyone who might stumble upon the issue:
Make sure you have configured both the system.diagnostics and the System.serviceModel/diagnostics sections configured.
Make sure you have them configured in the correct App.config/Web.config file. The thing to note is that multiple config files may exist in a project, and the one used depends on the Build Configuration.
Personally I had the very same symptom until I noticed that I put the sections
under app.config (in my case, client side tracing), instead of
app.DebugLocal.config. The later was used as my build configuration was set to DebugLocal.
I've got a duplex WCF service which hangs after the magic 10 proxy instantiations. The specific error on the client is:
"System.TimeoutException: This request operation sent to net.tcp://localhost:8080/RoomService/netTcp did not receive a reply within the configured timeout (00:00:59.9960000)".
There aren't any apparent error messages on the server.
Note that this isn't the standard, obvious problem, i.e., failing to close my proxy connections, as I'm closing every instance of my proxy connection appropriately before opening the next one:
try
{
client.Close();
}
catch (CommunicationException)
{
client.Abort();
}
catch (TimeoutException)
{
client.Abort();
}
catch (Exception)
{
client.Abort();
throw;
}
And I've set my throttling behavior to 500 simultaneous everything:
ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior()
{
MaxConcurrentCalls = 500,
MaxConcurrentSessions = 500,
MaxConcurrentInstances = 500
};
I've set the ConcurrencyMode of my service to Multiple, and I've tried all three possible values for InstanceContextMode.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
I've tried self-hosting the service, and hosting it within IIS, and I get the same results on each.
I've tried the NetTcpBinding, the WSDualHttpBinding, and the PollingDuplexBinding (on Silverlight), with the same results on each. I can't try the BasicHttpBinding or the WSHttpBinding, as this is a duplex service.
There was one place in my code where I was launching multiple threads (to execute multiple callbacks simultaneously), but for troubleshooting purposes I've commented that bit out, and it hasn't made a difference.
On the client, I've tried using new proxies for each test, and reusing the same proxy across all tests, but without any luck. I've tried creating a new InstanceContext for each proxy, and reusing the same InstanceContext across all proxies, and again, no luck.
Whatever I do, after the 10th test executed in my test harness, the next call to the service hangs.
Any thoughts on what I might be doing wrong?
OK, so I made at least one stupid mistake: I was creating the throttling behavior, but was neglecting to add it to the service proper. It's now added correctly:
ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior()
{
MaxConcurrentCalls = 500,
MaxConcurrentSessions = 500,
MaxConcurrentInstances = 500
};
base.Description.Behaviors.Add(throttlingBehavior);
And now I can run more than 10 tests, and hence my immediate problem is solved.
But I'm still puzzled as to why I'm running into this problem at all, since I'm specifically closing one proxy before moving on to the next. A MaxConcurrentXXX of 2 ought to be working in this scenario; I shouldn't need a MaxConcurrentXXX of 500. I'm a tad worried about scalability if every client that connects to the server continues to chew up a connection beyond the time that it's actually connected.
Maybe I'm making a stupid mistake somewhere else -- it wouldn't be the first time -- but I've specifically stepped through the code that's closing the proxy, and it's definitely getting called.
I've had this happen when I had a semaphore on the server-side which wasn't being released after a client was done being serviced.
Are any server-side resources or locks not being released properly? Since your service instance is per session, I'd suspect that the server object is hanging around and holding a lock. What if you change the behavior to per call?
I don't have an answer but I do have some debugging advice.
1) Attach the visual studio debugger to the service process and see if it can catch whatever is going on.
2) Configure the service behavior to pass exception information back to the client and see if the service is throwing an exception that isn't being reported:
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
3) Turn on service logging with ActivityTracing enabled and use the Service Trace Viewer (from Windows SDK) to analyze the log and see if anything pops up
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="Service.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
4) Isolate the service wrapper from the functional code and see if the service still hangs. If it doesn't then incrementally add functionality back until you figure out what is making it hang
5) If you are using an HTTP binding, proxy the service with fiddler and log the http traffic.
6) Try Hosting the WCF service in a Managed Windows Service and attach a debugger to the service process after you start it up.
Take a look at ServiceBehavior.AutomaticSessionShutdown.
At the begining of the Callback function in the client use
OperationContext.Current.Channel.Close();
This will solev the problem.
I'm retro-fitting an older vb.net application to bring it into compliance with LUA principles in Vista. Up until now, the application has used a hodgepodge of logging mechanisms, but the core one involved writing a log to c:\temp\ if the folder existed. I want to replace this current logging with a more standard logging mechanism.
This being VB, I decided to try using My.Application.Log in conjunction with app.config, and that works as far as it goes (though I didn't expect it to dump to the roaming profile). Unfortunately, the users are accustomed to troubleshooting with information from the log, as well as sending the log in when they submit a bug, and moving this log hides it pretty well.
My thought is to make the log a little more accessible by adding a link to it, or at least to the folder that contains it, in the app's UI. I don't know how to determine where that link will point, however.
Edit (Add'l info):
My configuration file is more or less the built-in default:
<system.diagnostics>
<sources>
<source name="Error Log" switchName="DefaultSwitch">
<listeners>
<add name="FileLog"/>
</listeners>
</source>
</sources>
<switches>
<add name="DefaultSwitch" value="Information" />
</switches>
<sharedListeners>
<add name="FileLog"
type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
initializeData="FileLogWriter"/>
</sharedListeners>
</system.diagnostics>
I'd like to set some of the properties on the FileLogTraceListener in the config file. The MaxSize, e.g. (There was a prior max-size behavior). I don't see any documentation that calls this out, though. (There is some community content at the base of the FileLogTraceListener page that suggests I should be able to, so I'll check that. I'd be much more comfortable if I found some official documented support for this, though.)
If I do that, I ought to be able to iterate through the trace listener collection on My.Application.Log and just link to the first FileLogTraceListener's FullLogFileName.
I believe this is configurable. It may be configured in the machine.config file, or you can override that in your application config file - which you will want to do so you can control it and create a link to it.
You will want to add a FileLogTraceListener to the app.config.
It goes in the system.diagnostics\sharedListeners section. You can specify the filename in the initializeData attribute.
More documentation from MSDN:
Walkthrough: Determining Where My.Application.Log Writes Information
Working with Application Logs in Visual Basic
Walkthrough: Changing Where My.Application.Log Writes Information
The solution is to use the Microsoft.VisualBasic.Logging.FileLogTraceListener. This trace listener supports retrieval of the full log path via its FullLogFileName property as well as customization of the location via the Location property.
One possibility might be to skip the My.Application.Log altogether and go straight to the System.Diagnostics.TraceListeners. I can choose my own log folder that way, and I'll definitely know where it's located.
I'm a fan of using the built-in Trace object for logging. Additionally, if you need to preserve the old behavior of using a temp file look at System.IO.Path.GetTempFileName().