在WCF中传递类型为数组的动态数据成员

本文关键字:数组 动态 数据成员 类型 WCF | 更新日期: 2023-09-27 18:30:05

在你开始为这篇文章的长度感到抱歉之前。。。

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

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

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

但是,当MessageDetails属性本身是ServiceOperationResponse类型的数组或列表时,如果我试图通过WCF传递ServiceOperationResponse对象,我会得到以下错误:

InnerException消息为"第1行位置576处出现错误"。元素'http://schemas.datacontract.org/2004/07/Library:MessageDetails'包含映射到名称的类型中的数据'http://schemas.datacontract.org/2004/07/Library:ArrayOfServiceOperationResponse"。反序列化程序不知道映射到此名称的任何类型。

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

其他类型的列表或数组可以毫无问题地传递,而且如果我在主ServiceOperationResponse中创建另一个ServiceOperationResponse[]类型的属性,即响应数组,并填充它,那么所有数据都会被正确地反序列化。然而,如果可能的话,我更希望不必只为一个特定的情况添加此属性。

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

在WCF中传递类型为数组的动态数据成员

WCF使用契约的概念进行通信。除其他外,合同规定了正在传输的数据的形状。这意味着你的运营合同必须有一个明确的形状;dynamic(或者更准确地说是Object,因为它在元数据中表示)没有定义良好的形状。

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

首先,我想问一下,为什么一开始就在DataContract中有一个动态属性。