I just finished writing the technical whitepapers for my product activation service, so I started the actual implementation using WCF services. All was good, added the usual WCF Service Application project, ran a quick F5, and swapped out all the default services with my own. Then I ran a F5 debug, and wait what? The WCF Test Client could not run my service.
Microsoft WCF Test Client
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
I vigorously checked the configuration, because I often write my by hand instead of using the WCF tool, and everything checked out. Here is what my configuration looked like, which is a valid configuration.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <compilation debug="true" /> </system.web> <system.serviceModel> <services> <service name="DCOMProductions.Activation.ActivationService"> <endpoint binding="wsHttpBinding" contract="DCOMProductions.Activation.IActivationService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:8732/Design_Time_Addresses/DCOMProductions.Activation/ActivationService/" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
What the heck? Because everything I could think of is valid, I then pointed my finger at something being wrong with my code. Something has to be causing the test client to fail. I tested this theory by navigating to the service address in Internet Explorer, which revealed that it was encountering a server error, which proved my theory.
Taking a look at my code, I quickly realized that I had some Composite Types in my service. One of the composite types is an Enum.
//----------------------------------------------------------------------------- // <copyright file="ActivationResult.cs" company="DCOM Productions"> // Copyright (c) DCOM Productions. All rights reserved. // </copyright> //----------------------------------------------------------------------------- namespace DCOMProductions.Activation { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; /// <summary> /// The result of the activation request /// </summary> [DataContract] public enum ActivationResult { [DataMember] None, [DataMember] Passed } }
If you notice, I have highlighted lines 21 and 23. The problem is that enumeration fields should use the EnumMemberAttribute, and not DataMemberAttribute. I changed the attributes, ran a F5 debug and low-and-behold, the service worked great.
If you find yourself pulling your hair out over WCF configuration problems, check your code too. It may just be something simple.
5 Comments
Leave a Comment
You must be logged in to post a comment.
Thanks for the above configuration. It worked pretty well for me. Thanks again
sorry serve wcf response
server should has some free space on disk to server wcf response.
Thanks for the post – helped me to refocus my attention and find the real bug in my code.
I received a similar exception because I’d placed a DataMember attribute on a read only property. Annoyingly it still compiled despite the error.
The solution was to create a private set method with an empty method body.
Hey! I’m glad my post helped. Unfortunately the cost of some of these abstractions like WCF is they have their own rules that live outside the constructs of compiler and language rules so they can be hard to catch. What would be nice is some way for WCF to throw a compiler error or warning if a rule is violated (eg. no set accessor or incorrect attribute usage). I’m sure we’ll get there one day as technologies improve and mature.