7

我有一个 WCF 服务,其中有接受非泛型基类作为参数的操作。

[DataContract]
class Foo
{ ... }

这个基类又被泛型类继承,例如

[DataContract]
class Bar<T> : Foo
{ ... }

为了让它工作,我以前必须为 Foo 类注册 KnownTypes,并让这些包括所有可能的 Bar 变体(例如Bar<string>Bar<int>甚至Bar<List<string>>)。

但是,使用 .NET 4 中的 DataContractResolver,我应该能够构建一个正确存储(和恢复)类的解析器。

我的问题:

  1. DataContractResolvers 通常只在服务端使用,而不是由客户端使用?如果是这样,在这种情况下这将如何有用?

  2. 编写一个序列化泛型类型的完全限定类型名称的 DataContractResolver 我错了吗,例如Bar`1[List`1[string, mscorlib], mscorlib]?客户端上的同一个 DataContractResolver 不能恢复这些类型吗?

4

3 回答 3

2

我以前用过DataContractResolver;这些是我的发现:

  1. 客户端和服务器都需要解析器;因为序列化和反序列化发生在两端。显然,使用了相同的 Resolver。
  2. 类型名称是 DataContractSerializer 生成的信息的标准部分。但是,它只是 NAME 类型,而不是完全(程序集)限定名称

基本上,自定义解析器允许您将其作为行为添加到 WCF 客户端和服务器:

`foreach (OperationDescription operation in myWCFService.Description.Endpoints[0].Contract.Operations)
    {
      operation.Behaviors.Find<DataContractSerializerOperationBehavior>()
          .DataContractResolver = new MyDataContractResolver();
    }`

对于客户端,您也可以这样做:

      `foreach (var operation in base.ChannelFactory.Endpoint.Contract.Operations)
  {
    operation.Behaviors.Find<DataContractSerializerOperationBehavior>()
        .DataContractResolver = new MyDataContractResolver();
  }`

我的解析器从配置的位置动态加载类型并基于某些属性缓存它们。如果您愿意,我可以为您提供一些示例代码 - 这都是非常基本的。

KnownTypeAttribute(例如使用提供的方法返回所有已知类型)也是可用的;但是自定义解析器允许更灵活的方法,例如动态加载类型(例如插件系统)和进行自己的映射(类型 => 类型名称,反之亦然)

于 2017-09-25T08:56:07.967 回答
1

我希望这在两端都有效,但我不确定这是一个好主意;它需要额外的配置,并且不适用于 Silverlight 等。但它可能适用于每端具有相同位的“完整”.NET。

于 2010-03-13T11:55:34.800 回答
0

不知道 DataContractResolver 的典型用例是什么,但根据这篇文章(DataContractResolver 上的 MSDN),这应该可以通过“SharedTypeResolver”和共享包含合同的程序集轻松完成。

提醒一句:虽然这似乎是可能的,但从设计的角度来看,我不太确定这是否是一个好主意,因为这会削弱合同的表现力。这些类型会破坏合同并破坏与其他编程语言的兼容性,这将导致一个问题,如果首先使用像 SOAP 这样的开放标准是正确的解决方案。DataContract 用于共享程序集...

于 2011-07-18T20:26:32.740 回答