Using MessageContracts and DataContracts


Users of the Service Factory often ask about the rationale behind the required use of MessageContracts even though the use of MessageContracts aren't mandated by WCF. I've answered this question in other venues, but it seemed like a good thing to put here in case I need to point others to it in the future.


If you ask the WCF product team when you should use a MessageContract versus a DataContract, their guidance usually revolves around the level of control you need over the message - like when you need to use custom SOAP headers*. You can find more detail in this topic of the WCF documentation. Their guidance makes complete sense if you think about the motivation they had when building WCF: to unify all of the Microsoft communication mechanisms into a single approach that is relevant to all scenarios. This is great for someone who has traditionally only done object-oriented or component-oriented development. They can be successful without understanding the nuances of building Web services.


In our experience one of the biggest hurdles for many developers who are new to Web services has been the concept of the message - rather than just passing around types like they've always done. You can characterize this distinction as implicit versus explicit message design. We have a topic in the Service Factory documentation that touches on this distinction. I think there is some room for improvement on this topic, but you can find it here nevertheless.


However, the confusion over a message isn't the only reason we elevate the importance of the message and recommend these usage patterns. We intentionally draw a clear distinction between types (both primitive types like string, and complex types like Customer) and messages (like ProcessExpenseReportRequest). From our perspective, DataContracts represent types and types are reusable. Messages are not used as types but rather the payload a method operates on - and it is not reusable since they are specific to the operation they are passed to and from. This level of distinction provides architects and lead developers a means of achieving better consistency throughout their organization by being more prescriptive about reusability.


I am aware that Juval's position is that MessageContracts are rarely needed. And, I hold Juval in the highest regard - I've not yet had an opportunity to learn what is motivating him to take this position. Some might argue that MessageContracts are just an additional (unnecessary) level of redirection. I can understand this point of view. We just feel the benefits greatly outweigh this nominal cost, and the feedback we've received from customers has been completely supportive of this approach.


* In my opinion, there is only one reason you would need to create a custom SOAP header that isn't already defined by a standards body like WS-*. (hint: if it's already defined elsewhere, you should use it to ensure interoperability, instead of "rolling your own") And, that reason is if you need to pass around localization information (like "en-us"). I don't think this is covered by any WS-* or other spec.

Comments (3)

  1. I agree that the messages are not shareable, but their underlying message (complex) type should be. E.g. a common DefaultRequestType could be shared between all operations that have no input to comply with message exchange pattern: one message in, one message out. Also, all XxxGeyById operations could share the message type IdCriterionRequestType. The instances of the message types are unique and define the operations (as when using Spring WS).

  2. Matt Brewer says:

    Thank you for validating the approach I’ve been pushing at my company.  There’s a lot of love for PODCs (plain ol’ Data Contracts) out there and it’s hard to get people off the data/type/object centric view and push them towards a more message-oriented way of thinking.  Yes… even in this day and age!

  3. I am constantly surprised when speaking with people how few have heard of or use the “Service Interface”

Skip to main content