Tuesday, May 8, 2012

WCF-MessageContract Basics


Message Contract

Sometimes you complete control over the structure of a SOAP message  is just as important as control over its contents then you can user message contracts both header and body content
Message is the packet of data which contains important information.
 WCF uses these messages to transfer information from Source to destination. WCF uses SOAP (Simple Object Access Protocol) Message format for communication.
Message Contract can be used to add and to get the custom headers in SOAP message

[DataContract]
public class CustomerCountry
{   
    [DataMember]
    public int Country;

}

[MessageContract]
    public class Customer
    {
        [MessageHeader]
        public int CustomerID;
        [MessageHeader]
        public string CustomerName;
        [MessageHeader]
        public CustomerCountry Country();

    }

Here we have  array of CustomerCountry type as message header so When this converted to SOAP Header it looks as shown below.
<Customer>
  <CustomerID>FD00001</CustomerID>
  <CustomerName>FundUS</CustomerName>
  <CustomerCountry>
    <Country>USA</Country>
    <Country>CANADA</Country>
    <Country>UK</Country>
  </CustomerCountry>
</Customer>

If you use the MessageHeaderArray attribute of CustomerCountry, SOAP message will looks different .MessageHeaderArray attribute which will serialize the array element independently and it is applicable to array only  not for collection.

<Customer>
  <CustomerID>FD00001</CustomerID>
  <CustomerName>FundUS</CustomerName> 
    <Country>USA</Country>
    <Country>CANADA</Country>
    <Country>UK</Country>
</Customer>


Another sample example is

[MessageContract]
class MailMessage
{
    // For example:
    // <To>u1@abc.com</To>
    // <To>u2@abc.com</To>
    // <To>u3@abc.com</To>
    // </summary>
    [MessageHeaderArray]
    public string[] To;
   
    [MessageHeader]
    public string From;

    [MessageBodyMember]
    public string Subject;

    [MessageBodyMember]
    public string Body;
}


Protection level :
Default protection level is  EncryptAndSign. you should set the protection level of each body part to the actual minimum protection level required.

[MessageContract]
public class PatientRecord
{
    [MessageHeader(ProtectionLevel = ProtectionLevel.None)]
    public int FundID;
    [MessageHeader(ProtectionLevel = ProtectionLevel.Sign)]
    public string FundName;
    [MessageHeader(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
    public string FundCategory;
    [MessageBodyMember(ProtectionLevel = ProtectionLevel.None)]
    public string FundCountry;
    [MessageBodyMember(ProtectionLevel = ProtectionLevel.Sign)]
    public string Fundlevel;
    [MessageBodyMember(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
    public string FundType;
}

Note :
For these security features to work, you must properly configure the binding and behaviors. If you use these security features without the proper configuration (for example, attempting to sign a message without supplying your credentials), an exception is thrown at validation time.




Names and Namespaces and Order

Order properity is only fro messagebody member abd default oder is alpehabetical

[MessageContract]
public class Funddetails
{
    [MessageHeader(Name = "ID", Namespace = "http://sample.mysample.com/message")]
    public string FundID;
    [MessageBodyMember(Name = "NAME", Order = 2)]
    public string FundName;
    [MessageBodyMember(Name = "category", Order=1 )]
    public string FundCategory;
  
}


Conrol Body Parts Are Wrapped


[MessageContract(IsWrapped = true)]
public class Funddetails
{
     [MessageBodyMember)]
    public string FundCategory;
  

}

SOAP MessageHeader Attributes

The SOAP standard defines the following attributes that may exist on a header:
Actor/Role (Actor in SOAP 1.1, Role in SOAP 1.2), MustUnderstandRelay

[MessageContract]
public class FundDetails
{
    [MessageHeader(Actor = "http://Muservices.service.com", MustUnderstand = true)]
    public bool FundID;
 
  
    [MessageBodyMember]
    public string FundCountry;
}

Performance Considerations


public class CustomerAccount
{
}

public class CustomerPurchase
{
}

Wrong Way

[MessageContract]
public class Customer
{
    [MessageHeader]
    public CustomerPurchase operation;
    [MessageBodyMember]
    public CustomerAccount InternalAccount;
    [MessageBodyMember]
    public CustomerAccount ExternalAccount;
    [MessageBodyMember]
    public int CountryID;
}

Correct Way
[MessageContract]
public class Customer
{
    [MessageHeader]
    public CustomerPurchase operation;
    [MessageBodyMember]
    public OperationDetails details;
}

[DataContract]
public class OperationDetails
{
    [DataMember]
    public CustomerAccount InternalAccount;
    [DataMember]
    public CustomerAccount ExternalAccount;
    [DataMember]
    public int CountryID;
}

No comments :

Post a Comment