Wednesday, 20 June 2012

RESTful WCF Service

Based on the Roy Fielding theory "Representational State Transfer (REST), attempts to codify the architectural style and design constraints that make the Web what it is. REST emphasizes things like separation of concerns and layers, statelessness, and caching, which are common in many distributed architectures because of the benefits they provide. These benefits include interoperability, independent evolution, interception, improved scalability, efficiency, and overall performance."
Actually only the difference is how clients access our service. Normally, a WCF service will use SOAP, but if you build a REST service, clients will be accessing your service with a different architectural style (calls, serialization like JSON, etc.).
REST uses some common HTTP methods to insert/delete/update/retrieve information which is below:
  1. GET - Requests a specific representation of a resource
  2. PUT - Creates or updates a resource with the supplied representation
  3. DELETE - Deletes the specified resource
  4. POST - Submits data to be processed by the identified resource
  5. HEAD
    Similar to GET but only retrieves headers and not the body
  6. OPTIONS
    Returns the methods supported by the identified resource
Advantages:
  1. Less overhead (no SOAP envelope to wrap every call in)
  2. Less duplication (HTTP already represents operations like DELETE, PUT, GET, etc. that have to otherwise be represented in a SOAP envelope).
  3. More standardized - HTTP operations are well understood and operate consistently. Some SOAP implementations can get finicky.
  4. More human readable and testable (harder to test SOAP with just a browser).
  5. Don't need to use XML (well, you kind of don't have to for SOAP either but it hardly makes sense since you're already doing parsing of the envelope).
  6. Libraries have made SOAP (kind of) easy. But you are abstracting away a lot of redundancy underneath as I have noted. Yes, in theory, SOAP can go over other transports so as to avoid riding atop a layer doing similar things, but in reality just about all SOAP work you'll ever do is over HTTP.

 we can understand by it following way:


Step(1) Cretae Interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
namespace WCFRESTService
{
[ServiceContract]
public interface IRestService
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "xml/{id}",
BodyStyle = WebMessageBodyStyle.Bare)]
string XMLProcess(string id);

[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "json/{id}")]
string JSONProcess(string id);
}
}

Step(2) Implements it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WCFRESTService
{
// NOTE: If you change the class name "RestService" here, you must also update the reference to "RestService" in Web.config.
public class RestService :IRestService
{
#region IRestService Members
public string XMLProcess(string id)
{
return "Your XML Processing ID is : " + id;
}
public string JSONProcess(string id)
{
return "Your JSON Processing ID is : " + id;
}
#endregion
}
}

Step(3) now setting configuration file as :
<system.serviceModel>
<services>
<service behaviorConfiguration="WCFRESTService.RestServiceBehavior"
name="WCFRESTService.RestService">
<endpoint address="" binding="webHttpBinding" contract="WCFRESTService.IRestService" behaviorConfiguration="WCFRESTService.webHttp">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFRESTService.RestServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WCFRESTService.webHttp">
<webHttp/>
</behavior>

</endpointBehaviors>
</behaviors>
</system.serviceModel>

Step(4) Now we can access it following way:




Tuesday, 19 June 2012

Throttling in WCF


WCF throttling provides some properties that we can use to limit how many instances or sessions are created at the application level. Performance of the WCF service can be improved by creating proper instance.


When WCF was first released in .NET Framework 3.0, the default values for WCF Service throttling settings such as MaxConcurrentSessions and MaxConcurrentCalls were set very conservatively. For example, here are the default settings in 3.0:
  • MaxConcurrentSessions (default: 10)
  • MaxConcurrentCalls (default: 16)
  • MaxConcurrentInstances (default: 26)


Attribute Description
maxConcurrentCalls Limits the total number of calls that can currently be in progress across all service instances. The default is 16.
maxConcurrentInstances The number of InstanceContext objects that execute at one time across a ServiceHost. The default is Int32.MaxValue.
maxConcurrentSessions A positive integer that limits the number of sessions a ServiceHost object can accept. The default is 10.

Service Throttling can be configured either Adminstractive or Programatically

Administrative(configuration file)

Using <serviceThrottling> tag of the Service Behavior, you can configure the maxConcurrentCalls, maxConcurrentInstances , maxConcurrentSessions property as shown below.
<system.serviceModel>
    <services >
      <service behaviorConfiguration="ServiceBehavior"  name="MyService">
        <endpoint address="" binding="wsHttpBinding" contract="IMyService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true "/>
          <serviceThrottling maxConcurrentCalls="500"
 maxConcurrentInstances ="100" 
maxConcurrentSessions ="200"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

References

How to handle Exception using Fault Contract in WCF



When we develop any WCF service, we will handle the exception using try- catch block. But these exceptions handlings are technology specific.In order to support interoperability and client will also be interested only, what wents wrong? not on how and where cause the error.So when we throw any exception from service, it will not reach the client side.WCF provides the way to handle and convey the error message to client from service using SOAP Fault contract.


We can understand this concept by using following example:


Step(1)Create Interface with datacontract for Fault contract and use   [FaultContract(typeof(MyException))] for AddNumber method.



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


namespace WCFFaultContract
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract()]
        [FaultContract(typeof(MyException))]
        int AddNumber(int First, int Second);
    }




    [DataContract()]
    public class MyException 
    {
        [DataMember()]
        public string ExTitle;
        [DataMember()]
        public string ExMessage;
        [DataMember()]
        public string InnerEx;
        [DataMember()]
        public string StackTrace;
    }


}


Step(2) Implements the interface  using fault contract as MyException



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


namespace WCFFaultContract 
{
    
    public class Service1 : IService1
    {
        public int AddNumber(int First, int Second)
        {
            //Do something
            MyException MyException = new MyException();
            MyException.ExTitle = "Error Funtion:AddNumber()";
            MyException.ExMessage = "Error while Adding number in AddNumber function.";
            MyException.InnerEx = "Inner exception message from serice";
            MyException.StackTrace = "Stack Trace message from service.";
            throw new FaultException<MyException>(MyException, "Reason: Testing the SOAP Fault contract");
        }


    }
}

OR--> Implements using try catch:



  public int AddNumber(int First, int Second)
        {
            try
            {
               // return 10;
                throw new Exception(); 
            }
            catch (Exception exx)
            {
                //Do something
                MyException MyException = new MyException();
                MyException.ExTitle = "Error Funtion:AddNumber()";
                MyException.ExMessage = "Error while Adding number in AddNumber function.";
                MyException.InnerEx = "Inner exception message from serice";
                MyException.StackTrace = exx.StackTrace; //"Stack Trace message from service.";
                throw new FaultException<MyException>(MyException, "Reason: Testing the SOAP Fault contract");
            }
        }

Step(3) Create Proxy and use it in the client side as bellow



 try
            {
                WCFFaultException.Service1Client proxy = new WCFFaultException.Service1Client();
                Console.WriteLine("Client is running at " + DateTime.Now.ToString());
                Console.WriteLine("Sum of two numbers... 2+2 =" + proxy.AddNumber(2,2));
                Console.ReadLine();
            }
            catch (FaultException<WCFFaultException.MyException> ex)
            {
                // Exception Handling code
            }


I hope this code will help you.....................................:)

Monday, 18 June 2012

Transaction in WCF

Transactions provide a way to group a set of actions or operations into a single indivisible unit of execution. A transaction is a collection of operations with the following properties(this is taken from MSDN):
  • Atomicity. This ensures that either all of the updates completed under a specific transaction are committed and made durable or they are all aborted and rolled back to their previous state.

  • Consistency. This guarantees that the changes made under a transaction represent a transformation from one consistent state to another. For example, a transaction that transfers money from a checking account to a savings account does not change the amount of money in the overall bank account.

  • Isolation. This prevents a transaction from observing uncommitted changes belonging to other concurrent transactions. Isolation provides an abstraction of concurrency while ensuring one transaction cannot have an unexpected impact on the execution of another transaction.

  • Durability. This means that once committed, updates to managed resources (such as a database record) will be persistent in the face of failures.
Windows Communication Foundation (WCF) provides a rich set of features that enable you to create distributed transactions in your Web service application.

We can understand by it following Example:

Step(1) Create WCF service and Add Attribute Interface Method with TransactionFlow as  [TransactionFlow(TransactionFlowOption.Allowed)]

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

namespace WCFTransaction
{

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        void InsertEmpDetails();
    }
}

Step(2) Implements Interface with attribute TransactionScopeRequired  as [OperationBehavior(TransactionScopeRequired = true)]

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

namespace WCFTransaction
{
 
    public class Service1 : IService1
    {
       [OperationBehavior(TransactionScopeRequired = true)]
        public void InsertEmpDetails()
        {
            // Insrt code will come here

        }
    }
}

Step(3)Create Service client and consume it.



Step(4)Enable Transaction flow using WCF Service Config File


  <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WCFTransaction" transactionFlow="true" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:1480/Service1.svc" binding="wsHttpBinding"
                bindingConfiguration="WCFTransaction" contract="WCFTransaction.IService1"
                name="WSHttpBinding_IService1">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>

Step(5) Now calling two objects of the service in one transaction

  For transaction we need to add  System.Transactions namespace.


  using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
            {
                try
                {
                    WCFTransaction.Service1Client obj = new WCFTest.WCFTransaction.Service1Client();
                    obj.InsertEmpDetails();
                    WCFTransaction.Service1Client obj2 = new WCFTest.WCFTransaction.Service1Client();
                    obj2.InsertEmpDetails();
                    ts.Complete();
                }
                catch (Exception ex)
                {
                    ts.Dispose();
                }
            }





So in the above manner we can enable transaction in WCF service.

Friday, 15 June 2012

WPF Application for Setting and getting properties using INotifyPropertyChanged Interface

This sample show how we can use INotifyPropertyChanged  Interface in WPF application. INotifyPropertyChanged is an interface used in the data object classes to provide PropertyChanged notification to clients when any property value gets changed.This allow us to raise PropertyChanged event whenever the state of the object changes (Added, Removed, and Modified).

Step(1) Create xaml file


<Window x:Class="WPFTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <TextBox Text="{Binding Path=StudentFirstName}" VerticalAlignment="Top" Height="18" Margin="99,83,57,0" />
     
        <TextBox Text="{Binding Path=StudentGradePointAverage}" Margin="99,113,57,127" />
     
    </Grid>
</Window>

Step(2) Code behind file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFTest
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        StudentData sd = new StudentData();
        public Window1()
        {
            InitializeComponent();
            this.DataContext = sd;
        }
    }
}

Step(3) Create data class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace WPFTest
{
    public class StudentData : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        string _firstName = "Shekhar";
        public string StudentFirstName
        {
            get
            {
                return _firstName;
            }
            set
            {
                _firstName = value;

                OnPropertyChanged("StudentFirstName");
            }
        }

        double _gradePointAverage=10;
        public double StudentGradePointAverage
        {
            get
            {
                return _gradePointAverage;
            }

            set
            {
                _gradePointAverage = value;
                OnPropertyChanged("StudentGradePointAverage");
            }
        }
    }
}

=============================================================

WPF MVVM Code Sample

This is simple WPF Application using MVVM design patterns.following code shows how we can design WCF application.

Step(1) First create xaml file



<Window x:Class="WPF_MVVM.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
 
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Grid.Row="0" Content="Example 2 - this works!" />
        <Label Grid.Column="0" Grid.Row="1" Content="Artist:  " />
        <Label Grid.Column="1" Grid.Row="1" Content="{Binding ArtistName}" />
        <Button Grid.Column="1" Grid.Row="2" Name="ButtonUpdateArtist"
        Content="Update Artist Name" Click="ButtonUpdateArtist_Click" />
    </Grid>

</Window>



Step(2) code behind file will be as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF_MVVM
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        #region Members
        SongViewModel _viewModel;
        int _count = 0;
        #endregion



        public Window1()
        {
            SongViewModel _viewModel = new SongViewModel();

            InitializeComponent();
            base.DataContext = _viewModel;

            //  We have declared the view model instance declaratively in the xaml.
            //  Get the reference to it here, so we can use it in the button click event.
            //_viewModel = (SongViewModel)base.DataContext;


        }

        private void ButtonUpdateArtist_Click(object sender, RoutedEventArgs e)
        {
            ++_count;
            _viewModel = (SongViewModel)base.DataContext;
            _viewModel.ArtistName = string.Format("Artist ({0})", _count);
        }

    }
}


Step(3)Create song.cs class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WPF_MVVM
{
    class Song
    {
        #region Members
        string _artistName;
        string _songTitle;
        #endregion

        #region Properties
        /// The artist name.
        public string ArtistName
        {
            get { return _artistName; }
            set { _artistName = value; }
        }

        /// The song title.
        public string SongTitle
        {
            get { return _songTitle; }
            set { _songTitle = value; }
        }
        #endregion

    }
}

Step(4) Create Model classs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace WPF_MVVM
{
    //class SongViewModel
    //{
    //    Song _song;

    //    public Song Song
    //    {
    //        get
    //        {
    //            return _song;
    //        }
    //        set
    //        {
    //            _song = value;
    //        }
    //    }

    //    public string ArtistName
    //    {
    //        get { return Song.ArtistName; }
    //        set { Song.ArtistName = value; }
    //    }

    //}



    public class SongViewModel : INotifyPropertyChanged
    {
        #region Construction
        /// Constructs the default instance of a SongViewModel
        public SongViewModel()
        {
            _song = new Song { ArtistName = "Shekhar", SongTitle = "RHTDM" };
        }
        #endregion

        #region Members
        Song _song;

        #endregion

        #region Properties
         Song Song
        {
            get
            {
                return _song;
            }
            set
            {
                _song = value;
            }
        }
        public string ArtistName
        {
            get { return Song.ArtistName; }
            set
            {
                if (Song.ArtistName != value)
                {
                    Song.ArtistName = value;
                    RaisePropertyChanged("ArtistName");
                }
            }
        }
        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Methods

        private void RaisePropertyChanged(string propertyName)
        {
            // take a copy to prevent thread issues
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }


}

Step(5) Application Output will be as follows: