3

Before you begin sorry for the length of this post...

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

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

The message details datamember is a dynamic type allowing any object to be passed simply. This works fine under nearly all circumstances as 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 itself an array or list of type ServiceOperationResponse I get the following error:

The InnerException message was 'Error in line 1 position 576. Element 'http://schemas.datacontract.org/2004/07/Library:MessageDetails' contains data from a type that maps to the name 'http://schemas.datacontract.org/2004/07/Library:ArrayOfServiceOperationResponse'. The deserializer has no knowledge of any type that maps to this name.

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

Other types of lists or arrays can be passed with no problems, also if I create another property of type ServiceOperationResponse[], i.e. an array of responses, in the main ServiceOperationResponse and populate this instead then all data is properly deserialized. However I would prefer if at all possible not to have to add this property just for 1 particular case.

/// <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; }
}

shown below is some sample code that will trigger a failure if I try to pass 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
        };
4

1 回答 1

1

WCF 使用合同的概念进行通信。除其他事项外,合同指定了正在传输的数据的形状。这意味着您的运营合同必须具有明确定义的形状;动态(或更准确地说是对象,因为它在元数据中表示)没有明确定义的形状。

您可以通过将 KnownTypeAttribute 添加到 DataContract 类来解决此问题,指定可以传输但未明确包含在合同类定义中的数据类型。但这只有在您提前知道动态属性中可能存在的每个对象的每种可能类型时才有效。

我首先要问为什么你在 DataContract 中有一个动态属性。

于 2012-04-04T17:58:38.017 回答