Passing a dynamic data member of an array of types in WCF

Before you start regretting the length of this post ...

Does anyone know why I can't pass an array of a class as a dynamic property through WCF?

I have a ServiceOperationResponse class that is used to pass messages around my solution as shown below.

The message details datamember is a dynamic type that allows you to easily pass any object. This works in almost any circumstance, since I can set the ServiceKnownType for each of the WCF server interfaces.

However, if I try to pass a ServiceOperationResponse object through WCF when the MessageDetails property is an array itself or a list of type ServiceOperationResponse, I get the following error:

The InnerException message was "Error at line 1 position 576. The element" http://schemas.datacontract.org/2004/07/Library:MessageDetails "contains data from the type that matches the name" http://schemas.datacontract.org / 2004/07 / Library: ArrayOfServiceOperationResponse. Deserializer does not know any type that matches this name.

This happens when I set the ServiceKnownType to any of the following: ServiceOperationResponse [], List.

Other types of lists or arrays can be passed without problem, also if I create another property of type ServiceOperationResponse [], that is, an array of responses, basically ServiceOperationResponse and populate it, and then all data is deserialized properly. However, I would prefer it if there was no need to add this property for just one particular case at all.

/// <summary>
/// Class used to pass details between services
/// </summary>
[DataContract]
public class ServiceOperationResponse
{
    /// <summary>
    /// the originating hostname or keyname
    /// </summary>
    [DataMember]
    public string HostName { get; set; }

    /// <summary>
    /// the operation name
    /// </summary>        
    public string OperationName { get; set; }

    /// <summary>
    /// the particular message details
    /// </summary>
    [DataMember]
    public dynamic MessageDetails { get; set; }
}

      

the below is a sample code that will crash if I try to stream back from WCF to a client

var responseList = new List<ServiceOperationResponse>();
        for (int i = 0; i < 3; i++)
        {
            var responseElement = new ServiceOperationResponse()
            {
                HostName = Environment.MachineName,
                MessageDetails = "this is a test"
            };
          responseList.Add(responseElement);
        }

        var response = new ServiceOperationResponse()
        {
            HostName = Environment.MachineName,
            OperationName = "Get a list of service responses",
            MessageDetails = responseList
        };

      

+3


source to share


1 answer


WCF uses the concept of contracts for communication. The contracts, among other things, determine the form of the transmitted data. This means that your work contract must be clearly defined; dynamic (or, more accurately, an object as represented in metadata) does not have a well-defined form.

You can work around this by adding a KnownTypeAttribute to your DataContract class, specifying the data types that can be passed but not explicitly included in the contract class definitions. But this will only work if you know in advance all the possible types of objects that may be present in the dynamic property.



I would start by asking why you have a dynamic property in the DataContract to begin with.

+1


source







All Articles