在WCF中传递类型数组的动态数据库

时间:2012-04-04 15:50:50

标签: c# wcf

在你开始抱歉这篇文章的篇幅之前......

有谁知道为什么我不能通过WCF将类的数组作为动态属性传递?

我有一个ServiceOperationResponse类,用于在我的解决方案周围传递消息,如下所示。

消息详细信息datamember是一种动态类型,允许简单地传递任何对象。 这在几乎所有情况下都能正常工作,因为我可以为每个WCF服务器接口设置ServiceKnownType。

但是,如果我尝试通过WCF传递ServiceOperationResponse对象,而MessageDetails属性本身就是ServiceOperationResponse类型的数组或列表,则会出现以下错误:

  

InnerException消息是'第1行中的错误576.元素'http://schemas.datacontract.org/2004/07/Library:MessageDetails'包含来自映射到名称'http://的类型的数据schemas.datacontract.org/2004/07/Library:ArrayOfServiceOperationResponse”。反序列化器不知道映射到此名称的任何类型。

当我将ServiceKnownType设置为以下任何一个ServiceOperationResponse [],List时会发生这种情况。

其他类型的列表或数组可以毫无问题地传递,如果我在主ServiceOperationResponse中创建ServiceOperationResponse []类型的另一个属性,即响应数组,并填充此代码,则所有数据都被正确反序列化。但是我更愿意,如果根本不需要为1个特定情况添加此属性。

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

如下所示是一些示例代码,如果我尝试从WCF传回客户端,将触发失败

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

1 个答案:

答案 0 :(得分:1)

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

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

我首先会质疑为什么你在DataContract中有一个动态属性开始。