WCF服务对象序列化

时间:2012-05-15 14:47:29

标签: c# wcf silverlight inheritance

我有一个名为contact的抽象类,另一个名为client的类继承自contact。我正在使用带有类型联系参数的方法处理WCF服务。 但是我拥有的是我想传递的客户端实例。 我面临这个错误:

  

不希望输入数据合约名称为'Client:http://schemas.datacontract.org/2004/07/xxx'的'xxx.Client'。将任何静态未知的类型添加到已知类型列表中 - 例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。

3 个答案:

答案 0 :(得分:7)

你想让DataContractSerializer知道Client是一种Contact

有几种方法可以做到这一点,但它们都围绕着使用KnownType属性或ServiceKnownType属性。

可以将KnownType放在Client类上,告诉DataContractSerializer它是Contact的KnownType。

[DataContract]
[KnownType(typeof(Client))]
public class Contact{}

KnownType也可以放在一个类上,表示在序列化这个类时你也可能会遇到另一个类。

如果您的DataContract类的属性为Contact且可能实际包含Client,则可能需要执行此操作:

[DataContract]
[KnownType(typeof(Client))]
public class Meeting
{
    Contact MeetingContact{get;}
}

在这种情况下,您可以在不指定客户端上的KnownType的情况下离开。如果您有一个返回集合的属性并且您想要指定集合中可以包含的类型,您可能还想这样做。

您可以指定静态方法的名称,而不是指定KnownType的实际类型,而该方法将返回已知类型:

[DataContract]
[KnownType("GetKnownTypes")]
public class Meeting
{
    Contact MeetingContact{get;}

    private static Type[] GetKnownType()
    {
    return new Type[]{typeof(Client)};
    }
}

您还可以通过configuration file指定已知类型。

ServiceKnownTypes以类似的方式工作,但在服务本身上指定:

[ServiceKnownType(typeof(Client))]
[ServiceContract()]
public interface IMyServiceContract
{

    [OperationContract]
    Contact GetContact();
}

此设置将让DataContactSerializer知道任何方法都可以返回类型Client的类型。以与已知类型类似的方式,您还可以使用静态方法来提供已知类型的服务。

答案 1 :(得分:5)

WCF不直接用于抽象类。您应在datacontract或服务类上使用KnownType属性。以下是例子;

[DataContract]
[KnownType(typeof(Client))]
public class Contact
{
   ...
}

[ServiceContract]
[ServiceKnownType(typeof(Client))]
public interface IMyService
{
    contact getcontact(Guid id);
}

答案 2 :(得分:2)

使用[KnownType][ServiceKnownType]属性确保关系。