Tuesday 2 July 2013

WCF - MessageContracts VS DataContracts

WCF: Message Contracts Vs Data Contracts

Most of the situations where services oriented applications are developed, there is no real necessity to have granular control on the SOAP message exchanged between the client and the service. But then why do we at all have message contracts been provided then? Is there a difference between data contracts and message contracts? For this article, I would assume we all know the definitions of both and have an understanding of each contracts. What I will try to explain is what is the difference at the messaging level (SOAP request and response) and the way client calls and passes parameters in case of a service which use only datacontracts and only messagecontracts.

1) When we introduce a message contract into an operation signature, we must use a message contract as the only parameter type and as the only return type of the operation. Whereas in case of using a data contract, the operation parameter and return type could be mixed with the simple types and void. This means that there is no partial use of message contracts.

ex.
Operation signature when using MessageContracts:
[OperationContract]
        UserContactInfoResponse GetUserDetails(UserContactInfoRequest UserInfo);
where UserContactInfoResponse and UserContactInfoRequest are both MessageContracts.

Operation signature when using DataContracts:
[OperationContract]
        UserContactInfoResponse GetUserDetails(int UserId);
where UserContactInfoResponse is a DataContract

2) MessageContracts help us to control the structure of SOAP message body and in turn allows us to control how it is serialized. This is especially helpful when interoperability is essential because we have control on how the SOAP message would be serialized.

The following is the part of the SOAP response (body) in case of the operation signature used for MessageContracts above (IsWrapped attribute of the MessageContract is true hence the MessageContract class name, UserContactInfoResponse, is appearing directly under SOAP body tag. If IsWrapped would have been false, the memberes would be directly listed under the body tag) :

<s:Body u:Id="_0">
    <UserContactInfoResponse xmlns="http://tempuri.org/">
      <UserInformation xmlns:a="http://schemas.datacontract.org/2004/07/MessageContractExample" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:EmailAddress>info@microsoft.com</a:EmailAddress>
        <a:Name>Microsoft</a:Name>
      </UserInformation>
    </UserContactInfoResponse>
  </s:Body>


Note that both the tags, UserContactInfoResponse (Message contract class) and UserInformation (Message contract element/a field in the Message contract class) are used in the service and they appear in the SOAP response body.

Now using the same operation signature ie. UserContactInfoResponse GetUserDetails(UserContactInfoRequest UserInfo);, when using DataContracts (i.e. where UserContactInfoResponse and UserContactInfoRequest are both DataContracts), the following is the SOAP response body

<s:Body u:Id="_0">
    <GetUserDetailsResponse xmlns="http://tempuri.org/">
      <GetUserDetailsResult xmlns:a="http://schemas.datacontract.org/2004/07/DataContractExample" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:EmailAddress>info@microsoft.com</a:EmailAddress>
        <a:Name>Microsoft</a:Name>
      </GetUserDetailsResult>
    </GetUserDetailsResponse>
  </s:Body>

As can be seen, the tag, GetUserDetailsResponse, is a default tag generated after the response is serialized and we have no operation or datacontract defined by this name.

Hence, for the same operation signature, the SOAP response body is different but what is striking is that MessageContract provides us control over the SOAP body.

When the client makes the method call using the proxy, the datacontract expects the data passed identical to the structure defined. What it means is that the method call would expect an instance of

UserContactInfoRequest to be passed as the method parameter. But in the case of MessageContracts, the parameters which are passed in the called method are the fields of the MessageContract and not the instance of UserContactInfoRequest.

In the code, this is evident in the following lines:

Inside CallDataContractOperation(): Task<DC.UserContactInfoResponse> tempres = (new DC.GetUserDetailsServiceClient()).GetUserDetailsAsync(req);

Inside CallMesssageContractOperation(): Task<MC.UserContactInfoResponse> tempres = (new MC.GetUserDetailsServiceClient()).GetUserDetailsAsync(req.LicenseKey,req.ExtraInformation);


3) MessageContracts allow us to access SOAP heades and pass such information which we do not or may not wish to pass in the SOAP body. This could be a session information or an authentication token (ex. license key or user credentials) or it could be signing or encrypting SOAP header information.

The following is the SOAP request where I am passing the license key to validate the request in case of MessageContracts (Note that IsWrapped attribute is true):

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://tempuri.org/IGetUserDetailsService/GetUserDetails</a:Action>
    <h:LicenseKey xmlns:h="http://tempuri.org/">12345</h:LicenseKey>
    <a:MessageID>urn:uuid:bae90c7c-3869-4db9-9d5f-8307f27f9ff1</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
  </s:Header>
  <s:Body>
    <UserContactInfoRequest xmlns="http://tempuri.org/">
      <ExtraInformation>ExtraInformation</ExtraInformation>
    </UserContactInfoRequest>
  </s:Body>
</s:Envelope>

The following is the SOAP request when passing the license key as a parameter (by defining it as an int field in UserContactInfoRequest) in case of DataContracts:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://tempuri.org/IGetUserDetailsService/GetUserDetails</a:Action>
    <a:MessageID>urn:uuid:c8eaf425-77bb-4505-9a2a-e0be1f6390f1</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
  </s:Header>
  <s:Body>
    <GetUserDetails xmlns="http://tempuri.org/">
      <UserInfo xmlns:d4p1="http://schemas.datacontract.org/2004/07/DataContractExample" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <d4p1:ExtraInformation>ExtraInformation</d4p1:ExtraInformation>
        <d4p1:LicenseKey>12345</d4p1:LicenseKey>
      </UserInfo>
    </GetUserDetails>
  </s:Body>
</s:Envelope>

The code is as follows:

Code in project containing Message Contract:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace MessageContractExample
{

    [ServiceContract]
    public interface IGetUserDetailsService
    {
        [OperationContract]
        [FaultContract(typeof(string))]
        UserContactInfoResponse GetUserDetails(UserContactInfoRequest UserInfo);
    }

     [DataContract]
    public class UserContactInfo
    {
        [DataMember]
        public string Name
        {
            get;
            set;
        }

        [DataMember]
        public string EmailAddress
        {
            get;
            set;
        }
    }

    [MessageContract(IsWrapped = true)]
     public class UserContactInfoRequest
     {
        [MessageHeader]
        public int LicenseKey;

        [MessageBodyMember]
        public string ExtraInformation;
     }

    [MessageContract(IsWrapped = true)]
    public class UserContactInfoResponse
    {
        [MessageBodyMember]
        public UserContactInfo UserInformation;
    }

public class GetUserDetailsService : IGetUserDetailsService
    {
        private const int ValidLicenseKey = 12345;
        public UserContactInfoResponse GetUserDetails(UserContactInfoRequest UserInfo)
        {
            if (UserInfo.LicenseKey == ValidLicenseKey)
            {
                UserContactInfoResponse UserInfoResponse = new UserContactInfoResponse();
                UserInfoResponse.UserInformation = new UserContactInfo();
                UserInfoResponse.UserInformation.Name = "Microsoft";
                UserInfoResponse.UserInformation.EmailAddress = "info@microsoft.com";
                return UserInfoResponse;
            }
            else
            {
                const string ErrorMessage = "Invalid License Key";
                throw new FaultException<string>(ErrorMessage,new FaultReason("License Key is not valid"));
            }
        }
    }

}


Code in project containing Data Contract only and no Message Contract:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace DataContractExample
{
    [ServiceContract]
    public interface IGetUserDetailsService
    {
        [OperationContract]
        [FaultContract(typeof(string))]
        UserContactInfoResponse GetUserDetails(UserContactInfoRequest UserInfo);
    }

    [DataContract]
    public class UserContactInfoResponse
    {
        [DataMember]
        public string Name
        {
            get;
            set;
        }

        [DataMember]
        public string EmailAddress
        {
            get;
            set;
        }
    }

    [DataContract]
    public class UserContactInfoRequest
    {
        [DataMember]
        public int LicenseKey
        {
            get;
            set;
        }

        [DataMember]
        public string ExtraInformation
        {
            get;
            set;
        }
    }

public class GetUserDetailsService : IGetUserDetailsService
    {
        private const int ValidLicenseKey = 12345;
        public UserContactInfoResponse GetUserDetails(UserContactInfoRequest UserInfo)
        {
            if (UserInfo.LicenseKey == ValidLicenseKey)
            {
                UserContactInfoResponse UserInfoResponse = new UserContactInfoResponse();
                UserInfoResponse.Name = "Microsoft";
                UserInfoResponse.EmailAddress = "info@microsoft.com";
                return UserInfoResponse;
            }
            else
            {
                const string ErrorMessage = "Invalid License Key";
                throw new FaultException<string>(ErrorMessage, new FaultReason("License Key is not valid"));
            }
        }

    }

}

Client Code (dont forget to add the service references and change the service namespaces with the ones you provide):

using System;
using System.Threading.Tasks;
using DC = CallingWCFServices.DataContractNamespace;
using MC = CallingWCFServices.MessageContractNamespace;

namespace CallingWCFServices
{
    class Program
    {
        static void Main(string[] args)
        {
            CallDataContractOperation();
            CallMesssageContractOperation();
            Console.ReadLine();
        }

        public static async void CallDataContractOperation()
        {
            DC.UserContactInfoRequest req = new DC.UserContactInfoRequest();
            req.LicenseKey = 12345;
            req.ExtraInformation = "Extra Information";

            DC.UserContactInfoResponse res = new DC.UserContactInfoResponse();
            Task<DC.UserContactInfoResponse> tempres = (new DC.GetUserDetailsServiceClient()).GetUserDetailsAsync(req);
            res = await tempres;

            Console.WriteLine("DataContractOperation: Name = {0} and Email = {1}", res.Name, res.EmailAddress);
        }

        public static async void CallMesssageContractOperation()
        {
            MC.UserContactInfoRequest req = new MC.UserContactInfoRequest();
            req.LicenseKey = 12345;
            req.ExtraInformation = "Extra Information";

            MC.UserContactInfoResponse res = new MC.UserContactInfoResponse();
            Task<MC.UserContactInfoResponse> tempres = (new MC.GetUserDetailsServiceClient()).GetUserDetailsAsync(req.LicenseKey,req.ExtraInformation);
            res = await tempres;

            Console.WriteLine("MessageContractOperation: Name = {0} and Email = {1}", res.UserInformation.Name, res.UserInformation.EmailAddress);
        }
    }
}



Sunday 23 June 2013

C# - Asynchronous programming using async and await

The asynchronous programming has moved on from the days when we need to use BeginInvoke/EndInvoke and a callback method to call a method asynchronously and get the result once the called method had

finished its execution. Since C# 4.0, there is a much simpler mechanism available to make the asynchronous calls. This is achieved by using async modifier and await keyword.

I tried my hand with asynchronous programming using this feature and have a few observations and would like to see if my understanding is correct. Here is my code

1) The new asynchronous calls rely heavily on tasks. Tasks can be thought of a piece of work which needs to be completed synchronously or asynchronously and might return a value. A task is run

inside a thread. So when we create a new task, effectively what we are doing is creating a new thread (from threadpool) and placing the task inside that new thread. In the code this is achieved

using StartNew method which creates an Action method and starts the task. This is evident with the managed thread id used in the code to show that a new thread is created hosting a new task by StartNew method.

2) The method marked as async are run in the main thread. They are not separate tasks and are the replacements for BeginInvoke and EndInvoke delegate methods. In the following code,

GetAttendeeDetailAsync is an async method executing in the same (main) thread which GetAttendeeDetailTask method asynchronously. The GetAttendeeDetailTask method creates and run a new Task (in a

new thread) and returns a Task<string>.

3) The return type of any async method can be void, Task or Task<T>. Starting from the call to the first async method, which can be called from a method having any return type or an event handler,

the return type of this called method should be void. The reason is that the calling method (ex. event handler) would otherwise need to convert the result returned as Task or Task<T> to appropriate

type. And since the calling method is not marked as async, it cannot use await to type cast the result.

4) In the code the return type of the async method, GetAttendeeDetailTask ,is Task<string>. What it means is that although it returns a string, the compiler wraps it into Task<string> while the

method is still running and the result is still awaited. The method GetAttendeeDetailTask is not an async method and hence should return a Task<string> and not a string type because we are not

using async/await on this method and hence the compiler will not perform the automatic type casts. If you see the value of the returning variable while debugging, it will not contain the actual

return value. What it will have is Status = Running and result = Not Yet Computed. This shows that the method execution is still not completed.

5) Await does the opposite. It casts the result returned as Task<string> to string. It actually unwraps a Task<T> type to the type T and returns the result when the async method execution finishes.

The code is as follows:
------------------------------------------------------------------------------------------------------------

using System;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncAndAwait
{

    class ConferenceCall
    {
        public delegate void IntimateAttendeesHandler(bool CallStarted);
        public event IntimateAttendeesHandler CallStartedEventRaisesEvent;  // Declare event in Publisher

        // Raising the event
        public void Run()
        {
            CallStartedEventRaisesEvent(true);
        }
    }

    class Attendee1
    {
        public void SubscribeToEventEvent(ConferenceCall conferenceCall)
        {

            conferenceCall.CallStartedEventRaisesEvent += new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);
        }

        // Callback Method
        public async void SubscribedMethod(bool CallStarted)
        {
            Console.WriteLine("Attendee1 is online");

            Task<int> Result = GetAttendeeDetailAsync();
            Console.WriteLine("Inside SubscribedMethod waiting.....");
            int length = await Result;
            Console.WriteLine("Main Thread Id:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
            Console.WriteLine(length.ToString());
        }

        // Callback Method

        public async Task<int> GetAttendeeDetailAsync()
        {
            try
            {
                Client objClient = new Client();
                Task<string> GetDetails = objClient.GetAttendeeDetailTask();
                Console.WriteLine("Awaiting in GetAttendeeDetailAsync");
                string retValue = await GetDetails;

                return retValue.Length;
            }
            catch (Exception ex)
            {
                return ex.ToString().Length;
            }
        }

    }

    class Client
    {
        public Task<string> GetAttendeeDetailTask()
        {
            Task<string> retValue = null;
            retValue = Task<string>.Factory.StartNew(() => GetResult());    // Creates and start an asynchronous operation
            return retValue;
        }

        public string GetResult()
        {
            Console.WriteLine("New Thread Id:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
            System.Threading.Thread.Sleep(10000);
            return "Name:CSharp;Age:12";
        }
    }
    class Test
    {

        ConferenceCall conferenceCall = new ConferenceCall();
        Attendee1 attendee1 = new Attendee1();

        public void Run()
        {
            attendee1.SubscribeToEventEvent(conferenceCall);
            conferenceCall.Run();
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Main Thread Id:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
            Test objTest = new Test();
            objTest.Run();
            Console.WriteLine("Inside Main_1");
            Console.WriteLine("Inside Main_2");
            Console.ReadLine();

        }
    }

}

The following image shows the value of the returning variable when the method execution is still not finished:


The following is the output of the program. note than the result '18' is returned with a time lag of 10 seconds and is not returned instantaneously because the thread sleeps for 10 seconds.


Thursday 16 May 2013

C# Delegate VS Event


Both Delegate instance and a delegate instance with event modifier are used to implement event publisher-subscriber design pattern. Without going into definitions of delegates and events, I will try to explain the difference between delegates and events (event keyword/modifier). In either cases, events are implemented using delegates.

Quoting from MSDN: "The publishing class defines a delegate. The subscribing class does two things: first, it creates a method that matches the signature of the delegate, and then it creates an instance of that delegate type encapsulating that method. When the event is raised, the subscribing class's methods are invoked through the delegate".



1) Delegate is a type whereas an event is only a modifier. This means a delegate can be declared outside of a class but an event cannot.

2) Although both delegate instance and a delegate instance with event modifier can be used to raise an event (to separate the events I have called the event generated by delegate as delegate event and event generated by delegate with event modifier as event event), the delegate event can be raised from other classes too and not just the class which contains the delegate event. Whereas an event event can only be raised by the class which contains the event.

3) Comparing the delegate declaration with an instance of delegate with event modifier (and not comparing the delegate instance with the instance of delegate with event modifier), obviously we need to first create a delegate instance to register the subscriber method with the delegate event and cannot register the subscriber method using only the delegate type (IntimateAttendees).

4) An event handler (method subscribed with the event), can be registered with the delegate event using either assignment operator (=) or subscribe operator (+=) whereas an event event (event using event modifier) uses only subscribe operator to register an event handler with the event.

5) A delegate instance cannot be declared in an interface (which is a field) whereas a delegate instance marked as event can. The compiler does not consider it a field.

I could not get a link to attach the code so, although the code is produced below, if you need the code files then please let me know and I shall send the code. Though the events are raised just like normal method calls, but my focus is to show the differences between delegate and event without engaging in too much code. Goes without saying, it can be refined to trigger the events as events and not as pure method calls.
_________________________________________________________________________________
Code:



using System;

namespace EventsAndDelegates
{
    #region Difference 1
    // Difference 1
    public delegate void OnlyATest(bool CallStarted);
    // The following code shows that delegate is a type where event is a only a modifier and not a type.
    // public event OnlyATestDelegate OnlyATestDelegateEvent;   // This will result in compilation error as no type is defined.
    #endregion Difference 1

    class ConferenceCall
    {
        public delegate void IntimateAttendeesHandler(bool CallStarted);
        public event IntimateAttendeesHandler CallStartedEventRaisesEvent;  // Declare event in Publisher - Event Event
        public IntimateAttendeesHandler CallStartedDelegateRaisesEvent;     // Declare event in Publisher - Delegate Event

        // Raising the event
        public void Run()
        {
            #region Conventional EventHandler using EventArgs base class
            // ConferenceCallEventArgs conferenceCallEventArgs = new ConferenceCallEventArgs(DateTime.Now, 2);
            // Conventially event handlers accept 2 parameters; source object and the specific information about the event (object derived from EventArgs)
            // The following call is useless as neither of the arguments are send but it is done to prove that the arguments can be different.
            // The ConferenceCallEventArgs can be used to refine this code so that it works in the conventional way.
            #endregion Conventional EventHandler using EventArgs base class

            CallStartedDelegateRaisesEvent(true);
            CallStartedEventRaisesEvent(true);

            #region Difference 2
            /*
             * The problem with raising the event using delegates is that it can be raised by other classes too and not just by the class
             * which publishes the event. In this case CallStartedDelegateRaisesEvent(true) can be called from the 'Test' class
             * defined subsequently in the code.
             * Whereas the event (same delegate type but using an event keyword) can only be raised by the class
             * which defines the event. In this case if we try to call CallStartedEventRaisesEvent(true) from the 'Test' class,
             * compiler will throw an error.
             * */
            #endregion Difference 2
        }
    }

    class Attendee1
    {

        #region Difference 3
        public void Difference2()
        {
            /*
             * The difference is not between the delegate and event instances. Rather comparing
             * delegate declaration with event instance. So not exactly a difference but worth noting.
             * Obviously we need to create a delegate instance to register the subscriber method with the delegate event.
             * And cannot add the subscriber method using only the delegate type (IntimateAttendees)
             * */
            ConferenceCall conferenceCall = new ConferenceCall();
            ConferenceCall.IntimateAttendeesHandler delegateInstance = new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);
            // The following will throw an error as we cannot use assignment operator while subscribing to an event
            // in case of event. In case of delegate its perfectly valid. This is Difference 4 which is shown later.
            // conferenceCall.CallStartedEventRaisesEvent = new ConferenceCall.IntimateAttendees(SubscribedMethod);
            conferenceCall.CallStartedEventRaisesEvent += new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);

            conferenceCall.CallStartedEventRaisesEvent -= new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);    // Unsubscribe the method.
        }
        #endregion Difference 3

        // Subscribing to event raised by delegate
        public void SubscribeToDelegateEvent(ConferenceCall conferenceCall)
        {

            conferenceCall.CallStartedDelegateRaisesEvent += new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);

        }

        // Subscribing to event raised by event
        public void SubscribeToEventEvent(ConferenceCall conferenceCall)
        {

            conferenceCall.CallStartedEventRaisesEvent += new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);

        }

        // Callback Method
        public void SubscribedMethod(bool CallStarted)
        {
            Console.WriteLine("Attendee1 is online");
        }


    }

    class Attendee2
    {
        // Subscribing to event raised by delegate
        public void SubscribeToDelegateEvent(ConferenceCall conferenceCall)
        {

            conferenceCall.CallStartedDelegateRaisesEvent += new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);
            #region Difference 4
            /*
             * The following code will also work (note that only assignment operator is used);
             * conferenceCall.CallStartedDelegateRaisesEvent = new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);
             * This will remove the methods already registerd with the CallStartedDelegateRaisesEvent event.
             * But if we replace the code in following method with the following line;
             * conferenceCall.CallStartedEventRaisesEvent = new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);
             * the compiler will not like it. The reason is the delegate instance CallStartedEventRaisesEvent is an event
             * (marked by event keyword) and hence the registration of the subscriber method (event handlers) with the event
             * is only possible through subscribe operator.
             * */
            #endregion Difference 4

        }

        // Subscribing to event raised by event
        public void SubscribeToEventEvent(ConferenceCall conferenceCall)
        {

            conferenceCall.CallStartedEventRaisesEvent += new ConferenceCall.IntimateAttendeesHandler(SubscribedMethod);

        }

        // Callback Method
        public void SubscribedMethod(bool CallStarted)
        {
            Console.WriteLine("Attendee2 is online");
        }
    }

    class Test
    {

        ConferenceCall conferenceCall = new ConferenceCall();
        Attendee1 attendee1 = new Attendee1();
        Attendee2 attendee2 = new Attendee2();

        public void Run()
        {
            attendee1.SubscribeToDelegateEvent(conferenceCall);
            attendee1.SubscribeToEventEvent(conferenceCall);

            attendee2.SubscribeToDelegateEvent(conferenceCall);
            attendee2.SubscribeToEventEvent(conferenceCall);

            conferenceCall.Run();
        }
     
    }

    interface ITest
    {
        #region Difference 5
        // A delegate instance cannot be declared in an interface (which is a field)
        // whereas an event instance can. The compiler does not consider it a field.

        // OnlyATest DelegateInstance       //Error
        #endregion Difference 5
        event OnlyATest EventInstance;
    }
 
}