MessageContract VS DataContract

The idea is to cover EVERYTHING with out going into detail.
A) Learning effort comparison

Data Contracts are easy to learn. Easy to visualise a scenario where data contracts can be used. Less points to cover.

Message contracts are comparatively difficult to learn. Message Contracts are used in  not-so-familiar scenarios. More learning points.
B) Definition Comparison

Data Contracts: Service tells client what kind of data is exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts. "Is the data Serialized?" is often asked in data contracts.
eg: an integer data-type might be available in both Service and the client. But a 
 'Account' class with 2 properties namely 'credit' and 'debit' may not be available in client. Use Data Contract in this scenario. Teaser: what is the use of KnownTypes then? ;)

Message Contracts: The focus is on the structure of a message rather then the contents.
Sometimes complete control over the structure of a SOAP message is just as important as control over its contents."Is it serialized?" is not important but "how or where or the format of serialization" is what you want to know in Message Contracts.
eg: The client wants to move some data from the body to the header. They think it is more secure in the header.

Sometimes you implement a wonderful data contract and then comes a requirement to encrypt a particular field and you are forced to convert data contract to message contract.

C) Implementation Comparison (only hints are given)

Data Contract
1) 2 attributes :-
          a) [DataContract] = class/structure/enum level
          b) [DataMember] = for fields/properties
There is infact two more not-so-known attributes 
          c) [EnumMember] = Enum members(used with [DataContract]).
          d) [Flag] = oops! I dont know. Something to do with sending multiple enum fields and is applied on enum.
2) Serialisation considerations
            1) EmitDefaultValue: default value to be serialised or not
            2) Order: order of serialization
            3) IsRequired: Must be present when reading or deserializing
            4) etc.
           eg: [DataMember(EmitDefaultValue = false)
3) forward compatiblilty with IExtensibleDataObject 
that is all!
[PS] 2 useful tips: 1) Serialization order(alphabetical) : (1)Base Class members ->  (2)members with out 'Order' property -> (3)members with order property (numerically ascending, when common then alphabetical)
                              2) Those members with out [DataMember] are omitted from serializing.

Message Contract
1) 3 Attributes :-
          a) [MessageContract] = class level
          b) [MessageHeader] = for fields/properties
          b) [MessageBodyMember] = for fields/properties
2) Provide a different formatting for array fields with [MessageHeaderArray] attribute(wrapping)
3) Encrypting/signing parts of messages
eg: [MessageHeader(ProtectionLevel=None)] 
4) Control how field appears in SOAP representation.
         a) name/namespace: 
                     eg: [MessageBodyMember(Name="transactionData")] 
                          public BankingTransactionData theData;
         b) wrapping of elements : eg: isWrapped (vs MessageHeaderArray)
5) Header specific properties like Actor, MustUnderstand
             [MessageHeader(Actor="http://auditingservice.contoso.com", MustUnderstand=true)] 
               public bool IsAudited;
6) Assigning properties like MustUnderstand through code(dynamic). And when both static and dynamic are present which one will be used. (dynamic overrides static)
7) Order of SOAP body parts appearing in SOAP
Teaser: How is message contract 'order' different from data contracts 'order' property? :)
8) Inheritance consideration: when same name given for fields in parent and child classes which one to take?
9) Performance consideration: can the number of [BodyMembers] be reduced by moving it to sub class,  thus reducing namespaces ?

D) Examples

Data Contracts
 namespace MyTypes
{
    [DataContract]
    public class PurchaseOrder
    {
        private int poId_value;

        // Apply the DataMemberAttribute to the property.
        [DataMember]
        public int PurchaseOrderId
        {

            get { return poId_value; }
            set { poId_value = value; }
        }
    }
}

Message Contracts

[MessageContract]
public class BankingTransaction
{
  [MessageHeader] public MessageHeader<bool> IsAudited;
  [MessageHeader] public Operation operation;
  [MessageBodyMember] public BankingTransactionData theData;
}
// application code:
BankingTransaction bt = new BankingTransaction();
bt.IsAudited = new MessageHeader<bool>();
bt.IsAudited.Content = false// Set IsAudited header value to "false"
bt.IsAudited.Actor="http://auditingservice.contoso.com";
bt.IsAudited.MustUnderstand=true;

And remember there are four type of contracts in WCF we learned two: 

MessageContract VS DataContract_第1张图片 

 

there is a same topic from the  codeproject.

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.

4. Can’t mix datacontracts and messagecontracts.

Because message-based programming and parameter-based programming cannot be mixed, so you cannot specify aDataContract as an input argument to an operation and have it return a MessageContract, or specify aMessageContract 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.

Hope this will help !!! 

 

in my experience . if you want to receive the MessageContract type info from the client request. you must use the Message option to receive in you receive activity. 

MessageContract VS DataContract_第2张图片 

otherwise you will get a error when the wf start.

MessageContract VS DataContract_第3张图片 

the parameter option is only for the DataContract. 

another thing you should remember, if you also use the sendreply activity paired with you receive activity. 

you must use the Message option to send replay response to the caller client just like you do in the receive activity. otherwise you will get a error when the wf start.

MessageContract VS DataContract_第4张图片 

and that WSDL description is different between message and data contract. as for the the message contract . you can find the relative info with the Message Contract type class fields name  .

< wsdl:message  name ="Customer" >
< wsdl:part  name ="CustomerID"  element ="tns:CustomerID" />
< wsdl:part  name ="FirstName"  element ="tns:FirstName" />
< wsdl:part  name ="LastName"  element ="tns:LastName" />
</ wsdl:message >
< wsdl:message  name ="CustomerService_AddLastName_InputMessage" >
< wsdl:part  name ="parameters"  element ="tns:AddLastName" />
</ wsdl:message >
< wsdl:message  name ="CustomerService_AddLastName_OutputMessage" >
< wsdl:part  name ="parameters"  element ="tns:AddLastNameResponse" />
</ wsdl:message >
< wsdl:portType  name ="CustomerService" >
< wsdl:operation  name ="CreateCustomer" >
< wsdl:input  wsaw:Action ="http://tempuri.org/CustomerService/CreateCustomer"  name ="Customer"  message ="tns:Customer" />
< wsdl:output  wsaw:Action ="http://tempuri.org/CustomerService/CreateCustomerResponse"  name ="Customer"  message ="tns:Customer" />
</ wsdl:operation >
< wsdl:operation  name ="AddLastName" >
< wsdl:input  wsaw:Action ="http://tempuri.org/CustomerService/AddLastName"  message ="tns:CustomerService_AddLastName_InputMessage" />
< wsdl:output  wsaw:Action ="http://tempuri.org/CustomerService/AddLastNameResponse"  message ="tns:CustomerService_AddLastName_OutputMessage" />
</ wsdl:operation >
</ wsdl:portType >
< wsdl:binding  name ="BasicHttpBinding_CustomerService"  type ="tns:CustomerService" >
< soap:binding  transport ="http://schemas.xmlsoap.org/soap/http" />
< wsdl:operation  name ="CreateCustomer" >
< soap:operation  soapAction ="http://tempuri.org/CustomerService/CreateCustomer"  style ="document" />
< wsdl:input  name ="Customer" >
< soap:body  use ="literal" />
</ wsdl:input >
< wsdl:output  name ="Customer" >
< soap:body  use ="literal" />
</ wsdl:output >
</ wsdl:operation >

.... 

and also you can see it more clear in the WF test Client tool.

MessageContract VS DataContract_第5张图片 

any comments are welcome . thanks  

see also :

good discription of DataContract and MessageContract and the Serialization mechanism of two .

http://www.cnblogs.com/artech/archive/2009/07/09/1520121.html 

http://www.cnblogs.com/artech/archive/2009/08/02/1536811.html

http://www.c-sharpcorner.com/uploadfile/dhananjaycoder/data-contract-hierarchy-in-wcf/ (ServiceKnownType and base-derived hierarchy class )

http://blogs.msdn.com/b/sajay/archive/2006/09/28/775330.aspx([DataContract(Name="ShapeWithDimensionsIn{0})])

 

你可能感兴趣的:(message)