如何使用 WCF 将派生类型序列化为其基类型

Posted

技术标签:

【中文标题】如何使用 WCF 将派生类型序列化为其基类型【英文标题】:How to serialize a derived type as its base type with WCF 【发布时间】:2011-05-07 15:45:00 【问题描述】:

我有一个公共库,里面有一些对象。然后我有一个服务项目,它引用公共库并从公共库中的对象创建一些派生类型。

我希望我的服务将派生类型序列化为公共库中定义的基本类型。

我不能对公共库中的对象使用 KnownTypes,因为我不希望公共库引用服务程序集。

那么我怎样才能让 wcf 将派生类型序列化为它们的基类型呢?

我希望我能做类似...

[DataContract(SerializeAsType = typeof(BaseType))] 公共类 DerivedType : BaseType

这样的事情可能吗?

【问题讨论】:

【参考方案1】:

我们刚刚通过设置继承类 [DataContract(Name="BaseClass")] “解决”了这个问题。即使继承的类是内部的并在另一个项目中定义,它也可以工作。

希望对你有帮助。

【讨论】:

嗨,马克。这就是你所做的一切吗?我们可以举一个更完整的例子吗? 是的,这就是所有需要做的事情。只需将合同重命名为基类的名称即可。 +1 对我来说,这是迄今为止最简单的解决方案。它是一种有效的衬里。 DataContractResolver 方法很长,涉及类和插入解析器服务器主机等。它唯一的可取之处是您可以逐个方法控制合同方法上的行为 - 其中此 Name= 解决方案适用于该对象的所有传输实例(就我而言,这没问题)。 只是指出如果您有多个已知的基类派生类型,这不起作用。在这种情况下,您还必须为每个派生类型声明一个单独的 NameSpace。这对尝试构建通用 Xpaths 映射到常见项目造成严重破坏。【参考方案2】:

您使用的是 .NET 4.0 吗?如果您是以下情况,您可以使用 DataContractResolver:

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractresolver.aspx

这也基本上是 Entity Framework 4.0 为代理类型的 DataContractResolver 所做的。

这是一个例子: Link

(请参阅链接中的 DeserializeAsBaseResolver)。

编辑: 如果您不使用 .NET 4.0,我认为您的下一个最佳选择是 DataContractSurrogate:http://msdn.microsoft.com/en-us/library/system.runtime.serialization.idatacontractsurrogate.aspx。 ...因此您可以手动控制序列化,但这可能会变得混乱。

两者都被传递到 DataContractSerializer 的构造函数中,并且可以通过 DataContractSerializerOperationBehavior 为 WCF 配置:http://msdn.microsoft.com/en-us/library/system.servicemodel.description.datacontractserializeroperationbehavior.aspx。

【讨论】:

我使用的是 3.5,所以我不得不选择代理选项......而且效果很好!谢谢

以上是关于如何使用 WCF 将派生类型序列化为其基类型的主要内容,如果未能解决你的问题,请参考以下文章

将派生类型序列化为 AppDomain 上的基本类型

将派生对象存储到其基类型的集合中——为啥它会起作用?

如何将 C# 匿名类型序列化为 JSON 字符串?

在 Asp.Net Web API 中将 JSON 反序列化为派生类型

如何让 System.Text.Json 将对象反序列化为其原始类型?

如何将 JSON 反序列化为正确类型的对象,而无需事先定义类型?