Tag Archive: wcf

Windows Communication Foundation

I recorded an hour and a half presentation on Windows Communication Foundation yesterday that you can view on YouTube here. The video is recorded in 1920×1080, and is uploaded at that quality. The presentation covers everything from what WCF is, to creating your first service and client, as well as a few other advanced subjects.

Resources
YouTube: http://www.youtube.com/watch?v=jaHc1Lbki-A&hd=1
PowerPoint: Windows Communication Foundation.pptx
Source Code: Routing Services.zip

FaultException`1 was unhandled when trying to deserialize parameter http://tempuri.org/:request

Microsoft .NET

I just finished my activation system which is just a WCF service, finished all the unit tests and ensured they passed and met requirements. Now its time to make a test client, so I load up Visual Studio and start a simple Console Application with the service reference to IIS Express, and boom! Failure. The WCF code that consumes the service is rather simple.

static void Main(string[] args) {
    ActivationServiceClient client = new ActivationServiceClient();

    ActivationRequest request = new ActivationRequest();
    request.DateCreated = DateTime.Now;
    request.MachineName = Environment.MachineName;
    request.ProductCode = Guid.NewGuid();
    request.ProductKey = "ABCDEFGHIJKLMNPQRSTUVWXYZ";

    ActivationResponse response = client.Activate(request);

    byte[] license = response.License;
    string licenseHash = response.LicenseHash;
    ActivationResult result = response.Result;
}

I highlighted line 10, because that’s where the failure is. Here’s the full exception.

FaultException`1 was unhandled
There was an error while trying to deserialize parameter http://tempuri.org/:request. Please see InnerException for more details.

I do the obvious and check the inner exception, but there is none. However I noticed there was a Details property with some extra data that read the following.

{An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.Runtime.Serialization.InvalidDataContractException: There was an error while trying to deserialize parameter http://tempuri.org/:request. Please see InnerException for more details. —-> System.Runtime.Serialization.InvalidDataContractException: No set method for property ‘ProductKey’ in type ‘DCOMProductions.Activation.ActivationRequest’. The class cannot be deserialized.

In short, it says that there is no set method for property `ProductKey`. This is true because the ActivationRequest structure is immutable by design. I designed the class so that the properties are initialized through constructor parameters, and the class itself is immutable. However, you will notice that on the client that consumes the service, the service reference created a type that is not immutable and has no constructor parameters. In addition, the type created by the service reference is mutable.

After thinking about the problem and doing some research I found that WCF requires two-way serialization by default. This means that by applying [DataMember] attribute on a property, it would need to have both the get and set accessors. While its not recommended to mark member fields as a DataMember, in this scenario it is the solution. Let’s take a look at some code.

private string name;
[DataMember]
public string Name {
    get {
        return name;
    }
}
[DataMember]
private string name;

public string Name {
    get {
        return name;
    }
}

The first code example would cause the WCF service to fail because it does not allow for two-way serialization, however the second would be fine since we are decorating the backing field as the DataMember instead of the read-only property. There’s really not much else to say here, but there are tradeoffs for one good practice over another. In this case we are trading the good practice of decorating properties as DataMembers for the good practice of immutable structures.

Cannot obtain Metadata from WCF service when using Microsoft WCF Test Client.

Microsoft .NET

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.