C# 在WCF中传递数组类型的动态datamember

C# 在WCF中传递数组类型的动态datamember,c#,wcf,C#,Wcf,在你开始之前,我为这篇文章的篇幅感到抱歉 有人知道为什么我不能通过WCF将类的数组作为动态属性传递吗 我有一个ServiceOperationResponse类,用于在解决方案中传递消息,如下所示 MessageDetailsDataMember是一种动态类型,允许简单地传递任何对象。 这在几乎所有情况下都可以正常工作,因为我可以为每个WCF服务器接口设置ServiceKnownType 但是,当MessageDetails属性本身是ServiceOperationResponse类型的数组或列

在你开始之前,我为这篇文章的篇幅感到抱歉

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

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

MessageDetailsDataMember是一种动态类型,允许简单地传递任何对象。 这在几乎所有情况下都可以正常工作,因为我可以为每个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'. 反序列化程序不知道映射到此名称的任何类型

当我将ServiceKnownType设置为以下任意一项,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; }
}
//
///类,用于在服务之间传递详细信息
/// 
[数据合同]
公共类服务操作响应
{
/// 
///原始主机名或密钥名
/// 
[数据成员]
公共字符串主机名{get;set;}
/// 
///操作名称
///         
公共字符串操作名{get;set;}
/// 
///特定消息的详细信息
/// 
[数据成员]
公共动态消息详细信息{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
        };
var responseList=新列表();
对于(int i=0;i<3;i++)
{
var responseElement=新服务操作响应()
{
HostName=Environment.MachineName,
MessageDetails=“这是一个测试”
};
响应列表。添加(响应元素);
}
var response=新服务操作响应()
{
HostName=Environment.MachineName,
OperationName=“获取服务响应列表”,
MessageDetails=responseList
};

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

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


我首先要问的是,为什么在数据契约中要有一个动态属性。

试试@AnuragRanjhan——感谢是一个很好的建议,但还是失败了。我猜这可能是DLR与WCF结合的一个bug。问题不大,因为我可以添加SeriveOperationResponse[]类型的额外属性,以便在必须传递父类数组时使用。一旦有了有效的解决方案,请发布它。我会很有兴趣去看的。