在你开始抱歉这篇文章的篇幅之前......
有谁知道为什么我不能通过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
};
答案 0 :(得分:1)
WCF使用合同概念进行沟通。除其他外,合同指定正在传输的数据的形状。这意味着您的操作合同必须具有明确的形状;动态(或更准确地说,对象,因为它在元数据中表示)没有明确定义的形状。
您可以通过将KnownTypeAttribute添加到DataContract类来解决这个问题,指定可以传输但未明确包含在合同类定义中的数据类型。但是,只有在事先知道动态属性中可能存在的每个对象的每种可能类型时,这才有效。
我首先会质疑为什么你在DataContract中有一个动态属性开始。