WCF MessageContract继承

时间:2009-08-24 09:12:51

标签: wcf inheritance messagecontract operationcontract

我对WCF很新,只是对如何正确获取MessageContract继承有疑问。我的设置的简化版本如下 - “基本”消息类型,然后是从其继承的另一个“测试”消息。

[MessageContract]
public abstract class BaseMessage
{ }

[MessageContract]
public class TestMessage : BaseMessage
{ }

然后我在ServiceContract上有一个异步的OperationContract定义为:

[OperationContract(AsyncPattern = true)]
IAsyncResult BeginFindRequest(BaseMessage request, AsyncCallback callback, object asyncState);

我得到的问题是在调用BeginFindRequest方法并传入请求参数的TestMessage实例时,WCF框架将TestMessage实例反序列化到服务/服务器端的BaseMessage。由于这被定义为抽象类,因此会导致以下错误:

  

“消息无法反序列化   到MessageContract类型BaseMessage   因为它没有默认值   (无参数)构造函数。“

从我在MessageContract继承中可以找到的有限信息来看,它似乎应该可以正常工作。

所以我的问题是 - 为了让这个工作,我错过了什么;或者我应该更专门针对该类型在ServiceContract上定义一个单独的OperationContract - 缺点是我最终会得到许多额外的OperationContracts?

5 个答案:

答案 0 :(得分:6)

最后,我发现这篇博文在头上发了钉 -

  

不幸的是合同的方式   用WCF表示非常   容易忘记他们的目的是什么:   定义发送给的消息   操作并从中发回   操作。实际上你必须这样做   想“我该如何表达这些数据   用XML格式?“ XML不支持   继承所以无论你放入什么   合同将不得不有一些   映射到XML的方式。数据   用于定义消息的合同   只是一种.NET类型的便利   用于为数据生成XML   你想通过 - 如果你看到它们   你注定要用的任何其他方式   痛苦的世界。所以想想数据   你想要通过,而不是如何通过   碰巧代表你的   业务层和设计你的   DataContracts相应。

http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,a3775eb1-b441-43ad-b9f1-e4aaba404235.aspx

因此,我将重构以提供具有显式合同类型的其他方法。这也将允许我通过删除所有类型检查来清理服务实现。

感谢您的帮助。

答案 1 :(得分:3)

好的,第一个问题是:你为什么真的使用Message契约?你真的需要吗?

通常,只有在需要严格控制SOAP消息的布局时才会使用消息协定,例如:要满足您需要调用的遗留系统,这需要特定的标题等。

“普通”WCF呼叫几乎不需要使用消息合同。

您可以使用[ServiceContract]定义服务调用(服务上的方法),并将数据结构传递为[DataContract]。如果你有一个DataContract,你可以有更多选择来处理你的服务中的继承/多态(更多的是使用消息契约构造)。

马克

答案 2 :(得分:0)

是否可以更改BaseMessage以使其成为具有无参数构造函数的具体类?

错误消息告诉我们无法初始化BaseMessage类型的对象,因为它是抽象的。

答案 3 :(得分:0)

该错误只是希望您拥有一个可以使用的默认空构造函数。但是,我同意marc_s;在我参与过的项目中,我很少使用消息合同,我记得的唯一一个案例就是文件传输服务的一部分,其中文件块在messasges中传递。

答案 4 :(得分:0)

尝试使用KnownType属性装饰[ServiceContract]。由于 TestMessage 不是来自公共操作的“可见”,这有助于管道知道在看到它时如何对待它。

如果这应该允许将[DataContract]序列化为 TestMessage ,您仍然可能需要通过“is a”或其他一些转换来处理多条消息。