I've been putting together a small WCF service that allows a client to upload a file to a server for processing. While the details of that are for another discussion, I want to focus on what should have been a simple operation but turned out to take up most of my afternoon and some of my evening: the generation of a client proxy class and configuration file.
By way of background, this particular WCF service is hosted by a simple Windows Service, runs (by default) under the Network Service account, and exposes a TCP end point for communication. I have a setup project that takes care of the installation and registration of the Windows Service and auto-runs it when installation is complete. This has been running great.
However, anytime I attempted to generate a proxy class for my service via the following command line, I would get some nasy error indicating that it “Cannot obtain Metadata from net.tcp://localhost:9999/myservice”.
svcutil net.tcp://localhost:9999/myservice/mex
My configuration file was as follows:
<?xml version="1.0" encoding="utf-8" ?><configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="mex"> <serviceMetadata /> </behavior> </serviceBehaviors> </behaviors> <services> <service name="MyService.ExampleSvc" behaviorConfiguration="mex"> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:9999/myservice" /> </baseAddresses> </host> <!-- default endpoint --> <endpoint binding="netTcpBinding" contract="MyService.IExampleSvc" /> <!-- metadata exchange (MEX) endpoint --> <endpoint address="mex" binding="mexTcpBinding" name="MEX" contract="IMetadataExchange" /> </service> </services> </system.serviceModel></configuration>
However, as I mentioned, everytime I attempted to retrieve the metadata via the /mex endpoint it failed. Right off the bat I suspected that the error had to do with the types used in the [ServiceContract] class, but I brushed that idea aside thinking that for sure it was something in the configuration file. So I kept on battling with it.
To that end, I created a very simple WCF service (in the same application) this time with an HTTP endpoint. I had to change the Windows Service credentials to a user with elevated permissions to register the HTTP channel (Network Service won't cut it) because I didn't want to manually mess with my HTTP security settings. Anyway, this was just a test. To my chagrin, it worked first try; I was able to retrieve the metadata.
So I returned to the TCP service.
Fortunately (and I'm no WCF whiz...yet :), I found a helpful behavior that I could add to the .config file that saved the day for me. By simply adding the <serviceDebug /> element with the includeExceptionDetailInFaults attribute to the mex behavior element I was able to get some diagnostics.
<serviceBehaviors> <behavior name="mex"> <serviceDebug includeExceptionDetailInFaults="true" /> <serviceMetadata /> </behavior></serviceBehaviors>
Now, in the big, fat, honkin' exception stack that was output I saw immediately that one of the embedded types used in my [ServiceContract] implementation had a nested type that was not serializable. Once I added [Serializable()] to the offending types (there were a few of them) and recompiled it worked like a champ! So it turns out that my initial suspiscion was correct...I need to listen to my intuition more often!
Powered by: newtelligence dasBlog 2.0.7226.0
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2010R. Aaron Zupancic
E-mail