10

我在理解 WCF 中的 ServiceKnownType 时遇到了一些麻烦。

取自此博客,以下代码不起作用:

[DataContract(Namespace = “http://mycompany.com/”)]
public class Shape{…}

[DataContract(Namespace = “http://mycompany.com/”)]
public class Circle : Shape {…}

[ServiceContract]
public interface IMyServer
{
    [OperationContract]
    bool AddShape(Shape shape);
}

.

IMyServer client = new ChannelFactory<IMyServer>(binding, endPoint).CreateChannel();

client.AddShape(new Circle());

它不起作用的原因是因为您试图添加一个圆圈,但服务合同只允许一个形状。你应该用 knowntypes 做一些事情,但我对它是如何工作的有点困惑。

既然该代码在服务中,为什么它不能自动知道 Circle 是从 Shape 派生的?此外,ServiceKnownType 实际上做了什么?

当 ServiceKnownType 放在 DataContract 之下时,显然它可以工作。我猜它说嘿,这种称为形状的特定对象类型也可以是圆形。我很难理解为什么它会这样做,因为如果你添加一个像 Square 这样的新类型,你将不得不为 Shape 类添加一个 ServiceKnownType 。如果它不能推断出来,将 KnownType 放到 Square 而不是 Shape 上岂不是有意义?所以 Square 说,嘿,我是一个 Shape,你不必摆弄 Shape 类吗?如果您的 Shape 类内置在库中,并且您想创建自己的衍生形状(如 DiamondShape),则无法将其添加到 Shape 类,因为您无权访问源代码。

4

1 回答 1

12

问题是 WCF 不会进入所有程序集并尝试查找所有可能的 Shape 子类型。它也不与 XML 文档一起传输类型信息(程序集、完全限定的类型名称)。

因此,虽然在传出的 XML 上生成标签“Circle”不会有问题,但传入的反序列化器不知道如何处理它。

KnownType“hack”就像一个必须由双方实现的已知类型的注册表。这是明确的。使用此注册表,反序列化程序知道“Circle”反序列化为类型 X,没有任何歧义的机会,也不必解析派生类型的所有可用或可访问程序集。

请记住,Square 并没有说“我是一个形状”,它是作为一个 XML 标记出现的,因此您不会轻易地自动知道要使用哪个 .NET 类。

于 2010-05-03T12:48:58.213 回答