首页 新闻 赞助 找找看

WCF-传输List<T>报序列化错误的问题

0
悬赏园豆:10 [已解决问题] 解决于 2016-12-15 12:07

如题,
问题描述:

 

[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项目,很多地方没思路,请大神帮忙看看。

new PersonBean()的主页 new PersonBean() | 初学一级 | 园豆:192
提问于:2016-12-15 11:52
< >
分享
最佳答案
0

DataSource上把所有派生类都加到KnownType里去,不然对方怎么知道要反序列化成啥?

收获园豆:8
Daniel Cai | 专家六级 |园豆:10424 | 2016-12-15 12:03

解决了,原来是这个原因,谢谢你。

new PersonBean() | 园豆:192 (初学一级) | 2016-12-15 12:06
其他回答(1)
0

你既然都发现就去改三 —— 不是List的问题,就是子类的问题。只要不子类就没问题。

收获园豆:2
花飘水流兮 | 园豆:13560 (专家六级) | 2016-12-15 11:56

谢谢你的回复,主要是不知道怎么改,没有思路

支持(0) 反对(0) new PersonBean() | 园豆:192 (初学一级) | 2016-12-15 11:58

@new PersonBean(): 写到这你肯定不想改掉前面的,因此你写个大类,返回List<大类>,里面有个属性叫做类型...后面的不用说了。

支持(0) 反对(0) 花飘水流兮 | 园豆:13560 (专家六级) | 2016-12-15 12:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册