5
votes

I am following a pattern that has objects for the Request and Response of a WCF service. I have multple request objects that have the same return type and name. Any help would be greatly appreciated.

I'm getting the following exception:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior contract: http://tempuri.org/:IService ----> System.InvalidOperationException: The Service.ServiceContract.IService.RetrieveUsers operation references a message element [http://tempuri.org/:WeekEndingId] that has already been exported from the Service.ServiceContract.IService.RetrieveDepartments operation. You can change the name of one of the operations by changing the method name or using the Name property of OperationContractAttribute. Alternatively, you can control the element name in greater detail using the MessageContract programming model.

Edit: I have used the Name attribute on the properties to give them unique names and this does resolve the issue but we are needing to use the name "WeekEndingId" for all requests. I would like to try and find a fix for this while still using the same name for the property.

Listed below are the classes that are causing the issues:

RetrieveDepartmentsRequest:

[MessageContract(WrapperName = "RetrieveDepartmentsRequest", WrapperNamespace = "http://Service.V1")]
    public class RetrieveDepartmentsRequest
    {
        [MessageBodyMember(Order = 0)]
        public int WeekEndingId { get; set; }

        [MessageBodyMember(Order = 1)]
        public string UserId { get; set; }

        [MessageBodyMember(Order = 2)]
        public string MachineName { get; set; }
    }

RetrieveUsersRequest:

[MessageContract(WrapperName = "RetrieveUsersRequest", WrapperNamespace = "http://Service.V1")]
public class RetrieveUsersRequest
{
    [MessageBodyMember(Order = 0)]
    public int WeekEndingId { get; set; }

    [MessageBodyMember(Order = 1)]
    public string UserId { get; set; }

    [MessageBodyMember(Order = 2)]
    public string MachineName { get; set; }
}

IService:

[OperationContract]
[FaultContract(typeof(ServiceFault))]
RetrieveDepartmentsResponse RetrieveDepartments(RetrieveDepartmentsRequest request);

[OperationContract]
[FaultContract(typeof(ServiceFault))]
RetrieveUsersResponse RetrieveUsers(RetrieveUsersRequest request);
3

3 Answers

2
votes

I believe it's a type conflict. In that: WeekEndingId is an int in RetrieveDepartmentsRequest and a decimal in RetrieveUsersRequest. Use MessageBodyMember's Name property to resolve the conflict. OR just change the name of the property in RetrieveUsersRequest.

OR BETTER yet: shouldn't WeekEndingId always be an int?

1
votes

This exception can also occur when using the MessageHeader attribute in a MessageContract. What I discovered is that all MessageHeaders which are used in across all OperationContracts within a given ServiceContract must contain a distinct "Name" for the data type used.

Basically you can't have OperationContracts: * void MethodA(MessageContractA a) * void MethodB(MessageContractB b)

where the MessageContractA object has a MessageHeader declared with a name "prop1" and the MessageContractB object has a MessageHeader declared with the same "prop1" name but a different data type.

This wrecks havoc on the Mex Metadata creation in conjunction with the wsdl.

0
votes

I believe that issue you are seeing is because the WrapperNamespace is the same for both objects. I think what you want to do is:

[MessageContract(WrapperNamespace = "USEFUL_NAMESPACE_HERE.RetrieveDepartmentsRequest")]

and

[MessageContract(WrapperNamespace = "USEFUL_NAMESPACE_HERE.RetrieveUsersRequest")]

or you could try:

[MessageContract(IsWrapped = false)]