我是相当新的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框架deserialising的的TestMessage实例BaseMessage的服务/服务器端。 由于这被定义为一个抽象类,它导致以下错误:
“该消息不能被反序列化为MessageContract类型BaseMessage,因为它不具有默认(无参数)构造”。
从有限的信息,我可以找到MessageContract继承,似乎它应该只是工作。
所以我的问题是 - 我是什么,为了得到这个工作丢失; 或者我应该也许,而不是定义上的ServiceContract一个单独的OperationContract的专门针对该类型 - 坏处是,我可以和许多额外的OperationContracts结束了?
最后,我发现这个博客帖子这击中了要害 -
不幸的合同在WCF使得表达的方式很容易忘记他们的目的是:定义消息发送到操作和发送从操作的恢复。 在现实中,你不得不思考“我将如何表达XML这些数据?”。 XML不支持继承所以无论你把合同将不得不有映射到XML的一些方法。 用于定义消息中的数据合同只是一个.NET类型的便利,用于生成要传递的数据XML - 如果你查看它们,你注定的痛苦的世界任何其他方式。 所以,想想你想传递,而不是如何可能发生在你的业务层表示并据此设计您的DataContracts数据。
http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,a3775eb1-b441-43ad-b9f1-e4aaba404235.aspx
因此,我将重构以提供一个明确的合同类型的另一种方法。 这也让我通过删除所有的类型检查清理服务实现。
感谢您的帮助。
OK,第一个问题是:为什么你真的使用Message合同? 你真的有需要一种?
通常情况下,消息合同只使用过的,当你需要严格控制的SOAP消息的布局,例如,以满足您需要调用哪些遗留系统需要特定的标题和这样。
“正常”的WCF调用应该几乎不需要使用消息合同。
您可以使用定义服务电话(您的服务的方法) [ServiceContract]
并且正在传递的数据结构[DataContract]
如果你有一个DataContract,你有更多的选择如何处理在服务继承/多态性(不是与消息合同建造更多)。
渣
这有可能改变BaseMessage使其与参数构造函数的具体类?
该错误消息告诉有没有办法来初始化类型BaseMessage的对象,因为它是抽象的。
该错误只是希望你有一个默认的空构造器,它可以使用。 不过,我同意marc_s; 在我很少使用的消息合约我工作的项目,我记得的唯一情况是因为其中的文件块是在messasges通过文件传输服务的一部分。
尝试装饰你的[ServiceContract]
与KnownType属性。 由于从的TestMessage公开操作不是“可见的”,这有助于管道知道如何当它看到它对待它。
如果这应该让[DataContract]
被序列化作为的TestMessage您仍可能需要通过不同的方式处理多个邮件“ is a
”或其他一些铸造。