我有一个WCF服务,其中有一些操作接受非泛型基类作为参数。
[DataContract]
class Foo
{ ... }
这个基类依次由
这样的泛型类继承[DataContract]
class Bar<T> : Foo
{ ... }
为了使这个工作起作用,我之前必须为Foo类注册KnownTypes,并且包括Bar的所有可能变体(例如Bar<string>
,Bar<int>
甚至{{1 }})。
但是,使用.NET 4中的DataContractResolver,我应该能够构建一个正确存储(和恢复)类的解析器。
我的问题:
DataContractResolvers通常只在服务端使用,而不是在客户端使用?如果是这样,在这种情况下如何有用呢?
编写一个DataContractResolver是错误的,它会序列化泛型类型的完全限定类型名称,例如Bar<List<string>>
?客户端上的DataContractResolver不能恢复这些类型吗?
答案 0 :(得分:1)
我希望能在两端工作,但我不确定这是一个好主意;它需要额外的配置,并且无法在Silverlight等上运行。但它可能适用于“完整”的.NET,每端都有相同的位。
答案 1 :(得分:1)
我之前使用过DataContractResolver
;这些是我的发现:
基本上,自定义解析器允许您将其作为行为添加到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(例如,使用提供的方法返回所有已知类型)也是可用的;但是自定义解析器允许更灵活的方法,例如动态加载类型(例如插件系统)和执行自己的映射(Type =&gt;类型名称,反之亦然)
答案 2 :(得分:0)
不知道DataContractResolver的典型用例是什么,但根据本文(MSDN on DataContractResolver),这应该可以通过“SharedTypeResolver”和共享包含合同的程序集轻松完成。
谨慎提醒: 因此,虽然这似乎是可能的,但从设计的角度来看,我不太确定这是否是一个好主意,因为这会削弱合同的表现力。这些类型会破坏合同并破坏与其他编程语言的兼容性,这将导致一个问题,即首先使用像SOAP这样的开放标准是正确的解决方案。 DataContract用于不共享程序集......