1. Comparison
Data Contracts
WCF data contracts provide a mapping function between .NET CLR types
that are defined in code and XML Schemas Definitions defined by the W3C
organization (
www.w3c.org/) that are used for communication outside the service.
you can say “Data contract is a formal agreement between a service
and a client that abstractly describes the data to be exchanged”. That
is, to communicate, the client and the service do not have to share the
same types, only the same data contracts. A data contract precisely
defines, for each parameter or return type, what data is serialized
(turned into XML) to be exchanged.
Message Contracts
Message contracts describe the structure of SOAP messages sent to and
from a service and enable you to inspect and control most of the
details in the SOAP header and body. Whereas data contracts enable
interoperability through the XML Schema Definition (XSD) standard,
message contracts enable you to interoperate with any system that
communicates through SOAP.
Using message contracts gives you complete control over the SOAP
message sent to and from a service by providing access to the SOAP
headers and bodies directly. This allows use of simple or complex types
to define the exact content of the SOAP parts.
2. Why use MessageContract when DataContract is there?
Data contracts are used to define the data structure. Messages that
are simply a .NET type, lets say in form of POCO (plain old CLR object),
and generate the XML for the data you want to pass.
Message contracts are preferred only when there is a need to
“control” the layout of your message(the SOAP message); for instance,
adding specific headers/footer/etc to a message.
Sometimes complete control over the structure of a SOAP message is
just as important as control over its contents. This is especially true
when interoperability is important or to specifically control security
issues at the level of the message or message part. In these cases, you
can create a message contract that enables you to use a type for a
parameter or return value that serializes directly into the precise SOAP
message that you need.
3. Why we use MessageContract to pass SOAP headers ?
Passing information in SOAP headers is useful if you want to communicate information “out of band” from the operation signature.
For instance, session or correlation information can be passed in
headers, rather than adding additional parameters to operations or
adding this information as fields in the data itself.
Another example is security, where you may want to implement a custom
security protocol (bypassing WS-Security) and pass credentials or
tokens in custom SOAP headers.
A third example, again with security, is signing and encrypting SOAP
headers, where you may want to sign and/or encrypt some or all header
information. All these cases can be handled with message contracts. The
downside with this technique is that the client and service must
manually add and retrieve the information from the SOAP header, rather
than having the serialization classes associated with data and operation
contracts do it for you.
When we use MessageContract ?
A
very simple answer to the question is, when you need a higher level of
control over the message, such as sending custom SOAP header, you then
use MessageContract instead of DataContract. But in my opinion, most of
the messaging needs can be catered by DataContracts.
This
is the extract from MSDN : Sometimes complete control over the
structure of a SOAP message is just as important as control over its
contents. This is especially true when interoperability is important or
to specifically control security issues at the level of the message or
message part. In these cases, you can create a message contract that
enables you to use a type for a parameter or return value that
serializes directly into the precise SOAP message that you need.
To
elborate on the above mentioned MSDN extract, a message contract allows
you to specifically control which elements will be in the SOAP header,
and which will be in the SOAP body and this isn't possible using the
DataContract. As DataContracts
represent types. Messages are not used as types but rather the payload a
method operates on and they are specific to the operation they are
passed to and from.
This
situation arises when you have a communication partner which requires a
very specific format and you have to tweak your SOAP messages to match
that given layout exactly. In my view, always use DataContracts unless you have to use MessageContract for a very good reason.
One
of the hypothetical situation could be your communication partner would
like to have a custom security header with username and hashed
password. So you could have a message contract something similar to the
below
02 | public class BankingTransaction |
04 | [MessageHeader] public string UserName; |
05 | [MessageHeader] public string Password; |
06 | [MessageBodyMember] private Account sourceAccount; |
07 | [MessageBodyMember] private Account targetAccount; |
08 | [MessageBodyMember] public int amount; |
Notice
on the above contract the UserName and Password are decorated with
MessageHeader attribute. The generated SOAP message with WCF
basicHttpBinding will look like following:
03 | < Action s:mustUnderstand = "1" |
13 | < sourceAccount >1234</ sourceAccount > |
14 | < targetAccount >5678</ targetAccount > |
Notice the SOAP the password and username
members are serialized as SOAP header and the remaining members were
serialized as SOAP body.
4. Can’t mix datacontracts and messagecontracts.
Because message-based programming and parameter-based programming cannot be mixed, so you cannot specify a DataContract as an input argument to an operation and have it return a MessageContract, or specify a MessageContract as the input argument to an operation and have it return a DataContract. You can mix typed and untyped messages, but not messageContracts and DataContracts. Mixing message and data contracts will cause a runtime error when you generate WSDL from the service.
No comments:
Post a Comment