C# 序列化基类(泛型列表)时WCF调用失败

C# 序列化基类(泛型列表)时WCF调用失败,c#,xml,wcf,serialization,inherited,C#,Xml,Wcf,Serialization,Inherited,我的结构如下: public class DerivedClass : List<BaseClass> { //Some helper methods used against the List of BaseClass properties //Methods public List<BaseClass> GetListOfBaseClasses() { return (List<BaseClass>)this;

我的结构如下:

public class DerivedClass : List<BaseClass>
{
   //Some helper methods used against the List of BaseClass properties

   //Methods
   public  List<BaseClass> GetListOfBaseClasses()
   {
       return (List<BaseClass>)this;
   }
}
我的WCF服务知道基类对象,但现在当我尝试调用该服务时,客户机将其派生为一个通用列表,如下所示:

DerivedClass classD;
FillData(classD)
List<BaseClass> baseClassList = classD.GetListOfBaseClasses();

using (IService myService = ObjectFactory.GetMyService())
{
      myService.DoSomething(baseClassList); //Method is expecting "List<BaseClass>"
}
我得到以下例外情况:

数据协定名称为“[某些URI文本]”的类型“DerivedClass”不可用 预期。考虑使用DATACONTractRelver或添加任何类型的 静态已知到已知类型列表-例如,通过使用 KnownTypeAttribute属性,或将其添加到 传递给DataContractSerializer的已知类型

我尝试以各种组合将这些属性添加到我的类中,但仍然没有成功:

[Serializable]
[KnownType(typeof(List<BaseClass>))]
[XmlInclude(typeof(List<BaseClass>))]
[KnownType(typeof(BaseClass))]
[XmlInclude(typeof(BaseClass))]
public class DerivedClass : List<BaseClass>
{
  /// ...
}

PS-Sheehs,我是唯一一个认为这个网站的输入字段很时髦的人吗?当我尝试格式化时,事情一直在变化…:|伟大的网站,无论我无法得到的想法,输入文字,因为我想

您必须向您的服务界面添加ServiceKnownTypeAttribute:

[ServiceKnownType(typeof(DerivedClass))]
public interface IService
{
    // Service declaration
}

您必须向服务接口提供ServiceKnownTypeAttribute:

[ServiceKnownType(typeof(DerivedClass))]
public interface IService
{
    // Service declaration
}
有几种方法可以解决这个问题。但首先,请研究有关数据合同和

请注意,您没有在DerivedClass基类上添加DataContract属性。尽管标有Serializable属性的类是有效的,并且可以在WSDL中公开,但DataContractAttibute具有为互操作性而设计的序列化规则,它是WCF的首选序列化机制

如果您决定在数据协定上注册已知类型,那么这就足够了:

[DataContract]    
public class DerivedClass : List<BaseClass>
{
  /// ...
}

[DataContract]
[KnownType(typeof(DerivedClass))]
public clas BaseClass
{
    //Add the DataMemberAttribute to the properties you want serialized.
}
如果要在服务合约级别注册已知类型,请在服务合约上添加ServiceKnownType属性。

有几种方法可以注册。但首先,请研究有关数据合同和

请注意,您没有在DerivedClass基类上添加DataContract属性。尽管标有Serializable属性的类是有效的,并且可以在WSDL中公开,但DataContractAttibute具有为互操作性而设计的序列化规则,它是WCF的首选序列化机制

如果您决定在数据协定上注册已知类型,那么这就足够了:

[DataContract]    
public class DerivedClass : List<BaseClass>
{
  /// ...
}

[DataContract]
[KnownType(typeof(DerivedClass))]
public clas BaseClass
{
    //Add the DataMemberAttribute to the properties you want serialized.
}

如果要在服务合约级别注册已知类型,请在服务合约上添加ServiceKnownType属性。

不确定这是否是最佳方法,因为这会将客户端代码临时耦合到服务接口。该服务只知道列表,不认为它应该关心客户如何发送该列表。假设另一个客户机想要子类化DerivedClass,那么服务器需要添加另一个属性。不要认为这对软件维护很有好处。所有派生类都将作为列表的包装器运行,以便它可以使用内置的通用列表运算符/方法来操作列表元素。当您无法控制服务代码时,这是一个值得关注的问题。不确定这是否是最佳方法,因为这会将客户端代码临时耦合到服务接口。该服务只知道列表,不认为它应该关心客户如何发送该列表。假设另一个客户机想要子类化DerivedClass,那么服务器需要添加另一个属性。不要认为这对软件维护很有好处。所有派生类的功能都是列表的包装器,因此它可以使用内置的通用列表运算符/方法来操作列表元素。当您无法控制服务代码时,这是一个值得关注的问题。BaseClass的定义如您所述。客户机只是从该类派生,以利用泛型列表运算符/方法;如果客户只是采用has-a方法,而不是is-a方法,那么实施就会起作用;也就是说,如果客户机不是从列表派生,而是将其作为属性。但这看起来很笨重。服务人员是否有必要了解列表的派生实现?似乎不是,客户需要将列表发送过来;客户端派生的CLS应该对服务隐藏,因为您不必在服务契约和数据契约级别添加它。一个就够了。另一种替代方法是配置文件或使用KnownTypectBibute.ctor,该文件以返回已知类型的IEnumerable的助手方法的名称作为参数。无论如何,我看不出你的派生类有什么意义。如果没有从示例和注释中看到的任何好处,它会使您的设计更难理解。删除派生类并在服务操作中使用IList或IEnumerable。通过这种方式,您可以封装集合类型,并拥有简单的可维护代码。只是辅助函数。类似于在列表上操作的函数;例如,将列表的所有项属性设置为给定某些条件的值,并根据列表计算某些值。基本上,所有的数据和操作都是连续的
在DerivedClass中创建,而不是在每次需要执行常见任务时创建一个单独的助手类。现在,如果你说有两个派生类和Helper是一个好的设计,我不同意。基类的定义正如你所说的。客户机只是从该类派生,以利用泛型列表运算符/方法;如果客户只是采用has-a方法,而不是is-a方法,那么实施就会起作用;也就是说,如果客户机不是从列表派生,而是将其作为属性。但这看起来很笨重。服务人员是否有必要了解列表的派生实现?似乎不是,客户需要将列表发送过来;客户端派生的CLS应该对服务隐藏,因为您不必在服务契约和数据契约级别添加它。一个就够了。另一种替代方法是配置文件或使用KnownTypectBibute.ctor,该文件以返回已知类型的IEnumerable的助手方法的名称作为参数。无论如何,我看不出你的派生类有什么意义。如果没有从示例和注释中看到的任何好处,它会使您的设计更难理解。删除派生类并在服务操作中使用IList或IEnumerable。通过这种方式,您可以封装集合类型,并拥有简单的可维护代码。只是辅助函数。类似于在列表上操作的函数;例如,将列表的所有项属性设置为给定某些条件的值,并根据列表计算某些值。基本上,所有的数据和操作都包含在DerivedClass中,而不是在每次执行常见任务时都需要创建一个单独的助手类。现在,如果你说有两个派生类和Helper是一个好的设计,我不同意。