5/19/11

WCF Service operations can’t be loaded due to mixing of message contract types and primitive types

When debugging your WCF Service, you may encounter the following error:
The operation could not be loaded because it has a parameter or return type of type System.ServiceModel.Channels.Message or a type that has MessageContractAttribute and other parameters of different types. When using System.ServiceModel.Channels.Message or types with MessageContractAttribute, the method must not use any other types of parameters
This basically means that a particular operation is using a combination of message contract types and primitive types in any of the following combinations:
  • MixType1: Contract type and primitive types as operation parameters
  • MixType2: Contract type as a parameter and primitive type as return type
  • MixType3: Primitive type as a parameter and Contract type as return type
Any of the scenarios listed above would generate the error. Let’s take a look at a ServiceContract that can generate this problem.
[ServiceContract]
public interface IRegisterMixed
{
        [OperationContract]
        Confirmation Register(string firstName, string lastName);

        [OperationContract]
        string RegisterComplex(Person person);
}

These are the message contract types:

[MessageContract]
public class Person
{
        public string FirstName { set; get; }
        public string LastName { set; get; }       
}

[MessageContract]
public class Confirmation
{
        public string AccountId { set; get; }       
}

The service contract generates the error because both operations are mixing contract types with primitive types. The Register operation has the operation parameters as primitive types and the return type as a contract type (MixType3). The RegisterComplex operation has a contract type as parameter and a primitive type as return type (MixType2).

A way to address this would be to modify the service contract as follows:

[ServiceContract]
public interface IRegisterOK
    {
        [OperationContract]
        string Register(string firstname, string lastname);
      
        [OperationContract]
        Confirmation RegisterComplex(Person person);
}

As you can see, both operations are consistently using either primitive types or contract types for both operation and return parameters.

I hope this tip would be useful when designing your next WCF Service operations.

og-bit.com