如题,
问题描述:
[DataContract]
[KnownType(typeof(DataSource))]
public class DataSource
{
private long? _id;
[DataMember]
public long? Id
{
get
{
return _id;
}
set
{
_id = value;
}
}
//省略若干属性
}
[DataContract] [KnownType(typeof(S7Plc))] public class S7Plc : DataSource{ //省略若干属性 }
[DataContract] [KnownType(typeof(Opc))] public class Opc : DataSource{ //省略若干属性 }
[ServiceContract()] public interface IDataSourceService{ [OperationContract] List<DataSource> getAllDataSource(); } public class DataSourceService : IDataSourceService { public List<DataSource> getAllDataSource() { List<DataSource> list = new List<DataSource>(); foreach (xxx) { if (条件1) { list.Add(S7Plc的实例); } else if (条件2) { list.Add(Opc的实例); } else { list.Add(DataSource的实例); } } return list; } }
客户端:
List<DataSource> result = client.getAllDataSource();
错误描述:
1、如果服务器端返回的list里面全是DataSource(父类)的实例时,客户端可以正常接收。
2、如果list里面有子类实例(S7Plc/Opc)时,客户端报错。
错误信息:
格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: getAllDataSourceResult。InnerException 消息是“元素“http://schemas.datacontract.org/2004/07/Model.Table:DataSource”含有来自映射到名称“http://schemas.datacontract.org/2004/07/Model.Table:S7Plc”的类型的数据。反序列化程序无法识别任何映射到此名称的类型。请考虑使用 DataContractResolver(如果你正在使用 DataContractSerializer),或将与“S7Plc”对应的类型添加到已知类型的列表。例如,通过使用 KnownTypeAttribute 属性,或者将它添加到传递给序列化程序的已知类型列表。”。有关详细信息,请参见 InnerException。
看起来是和序列化有关,初步考虑可能和泛型协变有关。
第一个WCF项目,很多地方没思路,请大神帮忙看看。
DataSource上把所有派生类都加到KnownType里去,不然对方怎么知道要反序列化成啥?
解决了,原来是这个原因,谢谢你。
你既然都发现就去改三 —— 不是List的问题,就是子类的问题。只要不子类就没问题。
谢谢你的回复,主要是不知道怎么改,没有思路
@new PersonBean(): 写到这你肯定不想改掉前面的,因此你写个大类,返回List<大类>,里面有个属性叫做类型...后面的不用说了。