如何在 WCF 中将接口标记为 DataContract
Posted
技术标签:
【中文标题】如何在 WCF 中将接口标记为 DataContract【英文标题】:how to mark an interface as DataContract in WCF 【发布时间】:2012-04-15 21:31:34 【问题描述】:我有两个数据类,它们只包含数据成员(没有函数)。一个是CallTask,另一个是SmsTask。这两个类有一些共同的属性,如 ID、Tel。我将这些通用属性放在一个单独的接口类中,并在适当的时候在我的项目中使用这个接口类。 现在我在我的项目中添加了一个 WCFService 来在客户端和服务器之间共享数据。考虑以下类设计:
public interface IGsmTask : IComparable
string TaskID get; set;
string SessionID get; set;
string Tel get; set;
class CallTask : IGsmTask
#region IGsmTask Members
public string TaskID get; set;
public string SessionID get; set;
public string Tel get; set;
#endregion
class SmsTask : IGsmTask
#region IGsmTask Members
public string TaskID get; set;
public string SessionID get; set;
public string Tel get; set;
#endregion
public string SmsText get; set;
在此设计中,我想将 CallTask、SmsTask 和 IGsmTask 托管给客户端,以便在服务方法中使用它们,如下所示;
[OperationContract]
public void AddTask(IGsmTask task)
我试图在 IGsmTask 上标记 [DataContract],但它给了我编译错误。没有任何方法可以将接口用作 DataContracts 吗?或者我应该如何在这个 synerio 中使用 KnownAttributes 类型? 谢谢。
【问题讨论】:
感谢 Reniuz 看来我不能为此目的使用接口。 WCF 是一个基于消息的 系统——客户端向服务器发送一个 XML 序列化的消息。因此,这些消息必须是具体类型,可以序列化为 XML 并用 XML 模式表示。接口不能序列化为 XML .... 我要做的第一件事是创建类来存储公共属性,而不是接口。这样,您在每个派生类中至少保存 3 行代码。 【参考方案1】:据我所知,使用接口作为数据合同是不可能的。另一方面,您可以使用基类并添加 knowntype 属性。
【讨论】:
我认为会有一种使用接口作为数据合约的方法。如果不可能,我将不得不将我的接口更改为基类。谢谢。 由于序列化是基于对象实例的,我认为没有直接的办法。【参考方案2】:Fer:只要设计得当,一切皆有可能。
如果问题是:
类是数据契约
&&
它的1个或多个属性必须是一个接口...
public interface ICustomInterface
int Property1 get;set
[DataContract]
public class MyClass
[DataMember(Name="_myInterface")]
public ICustomInterface MyInterface get;set;
问题是当反序列化发生时—— 无法将数据转换为实现 ICustomInterface 的类。
解决方案是创建一个实现接口的具体类,并将公共属性(即接口类型)的 getter/setter 转换为具体类的私有属性。
public class CustomInterfaceImplementor: ICustomInterface
public int Property1 get;set;
[DataContract]
public class MyClass
[DataMember(Name="_myInterface")]
private CustomInterfaceImplementor _MyInterface;
public ICustomInterface MyInterface
get return (_MyInterface as ICustomInterface);
set _MyInterface = (value as CustomInterfaceImplementor);
【讨论】:
创建一个新类意味着一切都必须重新初始化。如果您只想省略一些属性,这很麻烦。我认为这是另一种语言限制 它似乎只使用:get return _MyInterface; 设置 _MyInterface = 值; 所以你可以把 as 排除在外。以上是关于如何在 WCF 中将接口标记为 DataContract的主要内容,如果未能解决你的问题,请参考以下文章
在 WCF 的代码中将 IncludeExceptionDetailInFaults 设置为 true
如何在每个请求中将 winform 自定义用户凭据传递给 WCF 服务?