Before explaining Message contract, I will explain about the message. Message is a unit of communication and it is in the form of a packet. These packets travel for sharing the data. It is an envelope by which the communication completes between the client and Service. This envelope consists of two parts- one is header and other is body . Header is used to send the sensitive information such as credential and token key etc.
What is Message Contract?
WCF uses soap message for communicating between the two parties. Most of the time the programmers focus on implementing the data contract, serializing the data but sometimes they need more control over the message format, then they should use message contract.
Data contract basically controls the content of the soap message such as message body but Message contract controls the structure of the message. Data contract describes what type will be exchange between the two parties and message contract describes the structure of the soap message.
Message contract is involved in controlling the structure of soap message body. It is also used to send and receive the data into soap header. The data contract and operation contract creates soap message by default but it is only the message body content. Sometimes we need more control over soap message, as we want to part our message in two portions, where one should contain the sensitive data and other should contain the message body and we can think about the message contract and this is only the choice for doing this.
Some important things that should be known to each developer about the message contract are-
- When we pass the message contract in an operation parameter, only one parameter can be passed. If we do against this rule, run time error will occur.
- The operation that has a message contract in the parameters can return either message contract type or nothing.
- The operation will return the message contract type and also accept only message contract type as a parameter.
Let’s explain with an example. Suppose, I am developing a Service, which has an operation for authenticating to the student. After successful authentication, this method will return the detail of the student. To create this service, I need to create a Student class and this class is decorated with the data contract attribute.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.Web;
- namespace WcfService {
- [DataContract]
- public class Student {
- [DataMember]
- public string studentName {
- get;
- set;
- }
- [DataMember]
- public string studentId {
- get;
- set;
- }
- public string studentFees {
- get;
- set;
- } // this will not expose to client side because it does not hava DataMember Attribute
- }
- }
[OperationContract]
StudentLoginSussess LoginStudentAndGetDetail(StudentLogin login);
Token in StudentLogin class is decorated with Message Header attribute, which says this variable will come in header section of soap message and StudentName is decorated with MessageBodyMember attribute, which says it will come in body section of soap message.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- namespace WcfService {
- [MessageContract]
- public class StudentLogin {
- [MessageHeader]
- public string Token {
- get;
- set;
- }
- [MessageBodyMember]
- public string studentName {
- get;
- set;
- }
- }
- [MessageContract]
- public class StudentLoginSussess {
- [MessageBodyMember]
- public Student student {
- get;
- set;
- }
- }
- }
Message header says that the member, which is decorated with MessageHeader attribute will be the part of a message header. In other words, if we want to declare a member inside the message header, we must apply MessageHeader attribute on that member.
MessageBodyMember
Message Body Member says that the member, which is decorated with MessageBodyMember attribute will be the part of the message body. In other words, if we want to declare a member inside the message body, we must apply MessageBodyMember attribute before the member.
Now, the code of IStudentWcfService interface is there, where I declared all the operations of my Service but right now, I will show only one operation, which has a parameter of type StudentLogin and returns StudentLoginSussess.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.Text;
- namespace WcfService {
- // NOTE You can use the "Rename" command on the "Refactor" menu to change the interface name "IStudentWcfService" in both code and config file together.
- [ServiceContract]
- public interface IStudentWcfService {
- [OperationContract]
- StudentLoginSussess LoginStudentAndGetDetail(StudentLogin login);
- // NOTE: both classes are decorated with message contract.
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Sesrialization;
- using System.ServiceModel;
- using System.Text;
- namespace WcfService {
- public class StudentWcfService: IStudentWcfService {
- public StudentLoginSussess LoginStudentAndGetDetail(StudentLogin login) {
- Student student = new Student();
- // you can write here your login logic
- if (login.Token != "12121212") {
- string ex = "invalid user";
- throw new FaultException < string > (ex);
- }
- student.studentName = "Raj";
- student.studentId = "2";
- student.studentFees = "5000";
- StudentLoginSussess ob = new StudentLoginSussess();
- ob.student = student;
- return ob;
- }
- }
- }
- }
Please have a look on the given code. I am passing two parameters into this operation and this operation returns a Message Contract type.
public StudentLoginSussess LoginStudentAndGetDetail(StudentLogin login,string name) // this code is wrong, as it is only created to show the exception
- {
- Student student = new Student();
- // you can write here your login logic
- //if (login.Token != "12121212")
- //{
- // string ex = "invalid user";
- // throw new FaultException<string>(ex);
- //}
- student.studentName = "Raj";
- student.studentId = "2";
- student.studentFees = "5000";
- StudentLoginSussess ob = new StudentLoginSussess();
- ob.student = student;
- return ob;
- }

After seeing this error, I altered my code and then started debugging. Subsequently, it runs successfully.


Asit SinghPosted Oct 14, 2016, 1:37 PM
Thanks
Bhagwant SinghPosted Oct 14, 2016, 4:37 AM
Nice artical on Message Contract In WCF .