19 January 2012

reCAPTCHA : Free Captcha service for ASP.NET

What is reCaptcha?
  1. reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers and old time radio shows.
  2. It’s Free! Yep, reCAPTCHA is free.
  3. It’s Easy. reCAPTCHA is a Web service. As such, adopting it is as simple as adding
    a few lines of code on your site.
  4. It’s Accessible. reCAPTCHA has an audio test that allows blind people to freely
    navigate your site.
  5. It’s Secure. Most other CAPTCHA implementations can be easily broken.
  6. It’s Popular. Over 100,000 sites use reCAPTCHA, including household names like Facebook, Ticketmaster, and Craigslist.
  7. Whenever uses input data in reCaptcha control, they actually help digitizing books.
Moreover is very easy to integrate reCaptcha in our websites. Below are the steps
which are required to integrate it into a ASP.NET page.
Steps to Integrate reCaptcha in ASP.NET 

Step1:  Register for a reCaptcha key : As a first step we need to register for recaptcha keys. Navigate to Get reCaptcha URL to signup for the keys. After we register for the keys, we get a public and private keys which we need to use in our asp.net page. By default all keys work on localhost as well. 

Step2:  Download reCaptcha library for ASP.NET: Download the dll file from here. Also add the reference to the dll in the asp.net project. 
Step3:  Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:
Step4:  At the top of the aspx page, insert this: 
      <%@ Register TagPrefix="recaptcha" Namespace="Recaptcha" Assembly="Recaptcha" %>

Step5:  Then insert the reCAPTCHA control inside of the form tag and Enter your Publickey and PrivateKey
 <recaptcha:RecaptchaControl ID="recaptcha" runat="server" Theme="Red" PublicKey="" PrivateKey="" Height="30px" />
Step6:  Make sure you use ASP.NET validation to validate your form (you should check Page.IsValid on submission)
As an example I created a ASP.NET page whose markup and code behind code looks as given below:
Markup: (.aspx)


<asp:Label  Visible="true" ID="lblResult" runat="server" />
<recaptcha:RecaptchaControl ID="recaptcha" runat="server" Theme="Red" PublicKey="" PrivateKey="" Height="30px" />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" />

Code-behind(.aspx.cs)


protected void  btnSubmit_Click(object sender, EventArgs e)
    {
        recaptcha.Validate();
        if (recaptcha.IsValid)
        {
              if (Page.IsValid)
             {
                   lblResult.Text = "Captcha sucessfull!";
                   lblResult.ForeColor = System.Drawing.Color.Green;
             }
             else
            {
                 lblResult.Text = "Incorrect";
                 lblResult.ForeColor = System.Drawing.Color.Red;
             }
         }
    }

When I entered correct captcha text and pressed submit button following was the output:
 When I entered incorrect captcha text and pressed submit button following was the output:







  1. Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:










  2. Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:













  3. Download reCaptcha library for ASP.NET: Download the dll file from here. Also add the reference to the dll in the asp.net project.









  4. Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:










  5. Download reCaptcha library for ASP.NET: Download the dll file from here. Also add the reference to the dll in the asp.net project.









  6. Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:










  7. Download reCaptcha library for ASP.NET: Download the dll file from here. Also add the reference to the dll in the asp.net project.









  8. Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:










  9. Download reCaptcha library for ASP.NET: Download the dll file from here. Also add the reference to the dll in the asp.net project.









  10. Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:












  11. Download reCaptcha library for ASP.NET: Download the dll file from here. Also add the reference to the dll in the asp.net project.









  12. Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:







  13. Read more: http://www.techartifact.com/blogs/2011/01/recaptcha-free-captcha-service-for-asp-net.html#ixzz1jsTc1Pwi




  14. Download reCaptcha library for ASP.NET: Download the dll file from here. Also add the reference to the dll in the asp.net project.









  15. Add reCaptcha widget on ASP.NET page : Insert the reCAPTCHA control into the form you wish to protect by adding the following code snippets:






  16. 18 January 2012

    Steps for Session InProc Mode to Session StateServer

    Many articles are discussing about advantages of using Session StateServer or SQLServer over InProc Mode.  One basic reason why I choose StateServer Mode is when your website is running on Third Party Hosting than you will notice that Session Timeout can occur anytime depends on load of traffic on your server.

    If your website has large number of visitors and session timeout can cause problem, It is better to change Session Mode Session="InProc" to Session="StateServer".

    Main Advantage of Session StateServer (Best to choose while hosting on third party server)
    1.  Session is persistent and reliable.
    2. Avoid Session Timeout due to Memory shortage on server (IIS Setting).

    Main Disadvantage
    1. Poor Performance compare to Session="InProc"
    2. Session_End Event would not fire.

    Now lets understand 
    Steps for changing Session InProc Mode to Session StateServer Mode.

    Step 1:  Start Asp.net State Servcie
    1. Go to Control Panel > Administrative Tools > Services 
    2. Select Asp.Net State Service.
    3. Right Click on Asp.net State Service and choose start from popup menu.
     
    If you forget to Start Service you will receive following error.

    Server Error in '/' Application.

    Unable to make the session state request to the session state server. Please ensure that the ASP.NET State service is started and that the client and server ports are the same.  If the server is on a remote machine, please ensure that it accepts remote requests by checking the value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection.  If the server is on the local machine, and if the before mentioned registry value does not exist or is set to 0, then the state server connection string must use either 'localhost' or '127.0.0.1' as the server name.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.Web.HttpException: Unable to make the session state request to the session state server. Please ensure that the ASP.NET State service is started and that the client and server ports are the same.  If the server is on a remote machine, please ensure that it accepts remote requests by checking the value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection.  If the server is on the local machine, and if the before mentioned registry value does not exist or is set to 0, then the state server connection string must use either 'localhost' or '127.0.0.1' as the server name.



    Step 2:  Change Session Mode in Web.Config File
    <sessionState mode="StateServer"
                stateConnectionString="tcpip=127.0.0.1:42424"
                cookieless="false"
                timeout="120"/>
    Note: You can adjust timeout minutes based on your requirement.  Let the tcpip server to be localhost i.e. 127.0.0.1.  Most webhosting company uses these settings unless you have different IP for StateServer and  You are not required to change Port Number.


    Step 3: Make All Object Serializable
    You should make all object in your website to serializable.
    Note: To take advantage of Session StateServer or SQLServer or Custom Mode, object needs to be serialized.

    Example:  If your project contains class files for creating DAL (Data Access Layer), you should append Serializable to every class definition in order to make class Serializable.
     
    [Serializable]
    Class Department
    {
            long   _deptId;
            string _deptName;
            
            public long DeptId
            {
                   get {   return _deptId; }
                   set {  _deptId = value; }                  
             }

            public string DeptName
            {
                   get {   return _deptName; }
                   set {  _deptName = value; }                  
             }
    }

    IMPORTANT While doing Serialization
    Remember SQLConnection cannot be serialized.

    You might receive following error if you don't handle this situation.

    Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.Web.HttpException: Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.


    So to handle this situation you need to do following thing.

    1. Mark SQLConnection Object as NonSerialized
    [NonSerialized] protected SqlConnection _mainConnection;

    2. Mark your Class as Serializable and derive from IDeserializationCallback
    Example:
    [Serializable]
    Class Department: IDeserializationCallback
    {
            long   _deptId;
            string _deptName;
            
            public long DeptId
            {
                   get {   return _deptId; }
                   set {  _deptId = value; }                  
             }

            public string DeptName
            {
                   get {   return _deptName; }
                   set {  _deptName = value; }                  
             }

            //Create this Method Inside your Class
           void IDeserializationCallback.OnDeserialization(object sender)
            {
                //Recreate your connection here
                _mainConnection = new SqlConnection();
                _mainConnection.ConnectionString =
                        ConfigurationSettings.AppSettings["connStr"].ToString();           
            }
    }
     
    Reference Link: Click Here

    DataView.Table - Problem to Persist Sort or Filter View

    I was trying to Sort data with DataView and was trying to convert Dataview to table. I have notice even though view is sorted, when you try to convert it to table it would return only default sort.

    Example:
    //I was trying to perform something as following
    DataTable dtGrid = GetData();
    DataView dvSort = new DataView(dtGrid);
    dvSort.Sort = "CreationDate DESC";
    dtGrid = dvSort.Table; //Will Not Persist Sort Order

    In above example even though view is in sorted order, when i tried to convert it to table it would return only default view. In order to get Sorted view (Persist Sort order) instead of using DataView.Table you should use DataView.ToTable() method

    So if you changed above code with following it would start working as expected.

    DataTable dtGrid = GetData();
    DataView dvSort = new DataView(dtGrid);
    dvSort.Sort = "CreationDate DESC";
    dtGrid = dvSort.ToTable(); //Persist Sort Order

    Copy of Session Object

    Many times we try to make copy of session object, but in case when we are modifying copied object we might noticed that session object gets updated automatically, the reason is both copied object and session object are pointing to same location, even if you tried to use "new" operator while creating object.

    Scenario
    Let say you have Member Class as mentioned under
    public class Member
    {
            public string FirstName { get; set; }
            public string LastName { get; set; }
    }


    Problem:
    Member objMember = new Member();
    objMember.FirstName = "Sachin";
    objMember.LastName = "Tendulkar";

    Then try to save object in Session
    Session["MemberObj"] = objMember;

    This method will work good till we are just accessing object from session, but in case if we try to update object created from session it will update value of session also. That is,

    Member newMember = new Member(); //Even though object is created using "new" keyword.
    newMember = (Member) Session["MemberObj"];
    newMember.FirstName = "Kapil"; //This will update session FirstName also.

    Solution:
    To make copies of session you need to create a clone method in class. In above class create a method clone, to support copy of session.

    public class Member
    {
    public string FirstName { get; set; }
            public string LastName { get; set; }

    public Member clone()
         {
                Member cloneMember = new Member();
                 cloneMember.FirstName = this.FirstName;
                cloneMember.LastName = this.LastName;
    }
    }

    Now, while accessing session object, you can call clone method to make copy of session.

    Member newMember = new Member();
    newMember = ((Member) Session["MemberObj"]).clone();

    now if you try to modify object copied from session, will not update session object.
    newMember.FirstName = "Kapil"; //Will not update session FirstName

    Reference Link: Clickhere

    13 January 2012

    Extension Methods in C-Sharp

    You want to improve the syntax for calling common methods in your C# program, so that function names are shorter and easier to type. Extension methods provide a way to easily represent static methods as instance methods in the syntax of the C# language, which can be more intuitive and recallable for developers. Here we look at extension methods.


    Example

    Here is a custom extension method defined in a program written in the C# programming language. Generally, you will want to store your extension method class in a separate source file, such as "ExtensionMethods.cs" in your project. The file should store a static class with public static extension methods. In the rest of your source code, you can invoke these extension methods in the same way as you can call instance methods.
    Program that uses extension method on string [C#]
    
    using System;
    
    public static class ExtensionMethods
    {
        public static string UppercaseFirstLetter(this string value)
        {
     //
     // Uppercase the first letter in the string this extension is called on.
     //
     if (value.Length > 0)
     {
         char[] array = value.ToCharArray();
         array[0] = char.ToUpper(array[0]);
         return new string(array);
     }
     return value;
        }
    }
    
    class Program
    {
        static void Main()
        {
     //
     // Use the string extension method on this value.
     //
     string value = "dot net perls";
     value = value.UppercaseFirstLetter(); // Called like an instance method.
     Console.WriteLine(value);
        }
    }
    
    Output
    
    Dot net perls
     
    Description. In the first part of the program text, you can see an extension method declaration in the C# programming language. An extension method must be static and can be public so you can use it anywhere in your source code.
    The extension method is called like an instance method, but is actually a static method. The instance pointer 'this' is received as a parameter. You must specify the 'this' keyword before the appropriate parameter you want the method to be called upon. In the method, you can refer to this parameter by its declared name.

    This-keyword in parameter list. The only difference in the declaration between a regular static method and an extension method is the 'this' keyword in the parameter list. If you want the extension method to received other parameters as well, you can place those in the method signature's parameter list after the 'this' parameter.
    Calling extension method. You can call an extension method in the same way you call an instance method. In Visual Studio, an extension method in IntelliSense is represented by a different icon that has a downward arrow on it. You can use this icon to differentiate between instance and extension methods before calling them. Also the text "(extension)" is used in IntelliSense.
     

    What’s the Specification of an Extension Method?

    An extension method is a special kind of static method that allows you to add new methods to existing types without creating derived types. The extension methods are called as if they were instance methods from the extended type, For example: x is an object from int class and we called it as an instance method in int class.

    How to Create my Extension Method?

    Simply, you create your own static method in your class and put this keyword in front of the first parameter in this method (the type that will be extended).

    General Tips in Extension Methods Usage

    This section is optional reading section for understanding the core idea of extension methods:
    1. This keyword has to be the first parameter in the extension method parameter list.
    2. Extension methods are used extensively in C# 3.0 and further version specially for LINQ extensions in C#, for example:
    3. It is important to note that extension methods can't access the private methods in the extended type.
    4. If you want to add new methods to a type, you don't have the source code for it, the ideal solution is to use and implement extension methods of that type.
    5. If you create extension methods that have the same signature methods inside the type you are extending, then the extension methods will never be called.

     

    23 December 2011

    ASP.NET AJAX Calendar Extender – Tips and Tricks

    The CalendarExtender is an ASP.NET AJAX control that is associated with a TextBox control. When the user clicks on the TextBox, a client-side Calendar control pops up. The user can then set a date by clicking on a day, navigate months by clicking on the left and right arrow and perform other such actions without a postback. In this article, we will see some tips and tricks that can be applied to a CalendarExtender control. 

    If you are new to the CalendarExtender control, you can check out some information about it over here.


    I assume you have some basic experience developing ASP.NET Ajax applications and have installed the ASP.NET Ajax Library and ASP.NET Control Toolkit. As of this writing, the toolkit version is Version 1.0.20229 (if you are targeting Framework 2.0, ASP.NET AJAX 1.0 and Visual Studio 2005) and Version 3.0.20229 (if targeting .NET Framework 3.5 and Visual Studio 2008).
    All the tips shown below have been created using Version 3.0.20229 (targeting .NET Framework 3.5 and Visual Studio 2008).
    Tip 1: How to display and hide a Calendar on the click of a Button
    If you want to popup a Calendar on the click of a button, you can use set the PopupButtonID of the CalendarExtender to the ID of the button. In this case, we will be using an ImageButton as shown below:
           <asp:ImageButton runat="Server" ID="ImageButton1" ImageUrl="~/Images/Icon1.jpg" AlternateText="Click here to display calendar" />
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
           
            <cc1:CalendarExtender ID="CalendarExtender1" runat="server"
            TargetControlID="TextBox1" PopupButtonID="ImageButton1"/>
    If you are using an earlier version of the toolkit, you may observe that the ImageButton causes a postback when you click on it again, to close the Calendar. To avoid the postback, use a HTML Image Control instead of the Server side Image Control as shown below:
           <img alt="Icon" src="/Images/Icon1.jpg" id="Image1" />
           <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
           
            <cc1:CalendarExtender ID="CalendarExtender1" runat="server"
            TargetControlID="TextBox1" PopupButtonID="Image1"/>
    Note: In case you are clicking on the textbox to open the calendar, then in earlier versions of the toolkit, the calendar would not hide automatically when the user clicked anywhere outside the Calendar control. However this was fixed in the later versions. In fact, in the latest version, the Calendar hides automatically when a date is selected.
    If for some reason you are facing issues with the Calendar not hiding automatically, make sure that you have the latest version of the AJAX Control Toolkit.
    Tip 2: How to Add a CalendarExtender to a GridView
    If you want to add a CalendarExtender to a GridView, use a template field with a TextBox and CalendarExtender as shown below:
        <form id="form1" runat="server">
            <asp:ScriptManager ID="ScriptManager1" runat="server" />
            <div>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="CategoryID"
                DataSourceID="SqlDataSource1" ShowFooter="true" AllowPaging="True" AllowSorting="True">
                <Columns>           
                   <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
                     SortExpression="CategoryID" />
                      <asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
                     SortExpression="CategoryName" />
                  <asp:TemplateField>
                    <ItemTemplate>
                        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                        <cc1:CalendarExtender ID="CalendarExtender1" runat="server" TargetControlID="TextBox1"/>
                    </ItemTemplate>
                </asp:TemplateField>               
                </Columns>
            </asp:GridView>
            <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="Data Source=SUPROTIM;Initial Catalog=Northwind;Integrated Security=True"
                SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]" >
            </asp:SqlDataSource>
            </div>
        </form>
    Tip 3: Enable Year Navigation in CalendarExtender
    When the calendar appears, click on the title of the calendar to change the view to Months in the current year. Clicking it again, switches the view to Years, showing 10 years at a time.
    If you plan to do this programmatically, here’s some code for you. Use the OnClientShown event and switch the mode using javascript. This tip was shared by one of the Microsoft® support person at the asp.net forums.
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
     <cc1:CalendarExtender ID="CalendarExtender1"
    runat="server" TargetControlID="TextBox1" OnClientShown="ChangeCalendarView" />
    Then add this to the <head> section
    <head runat="server">
    <title>CalendarExtender</title>
    <script type="text/javascript">
    function ChangeCalendarView(sender,args)
    {
       sender._switchMode("years", true);           
    }
    </script>
    </head>
    Tip 4: Display only the day and month in the CalendarExtender
    To select only the day and month without the year, use the Format property of the CalendarExtender and set it to “dd/MM” as shown below:
    <cc1:CalendarExtender ID="CalendarExtender1" runat="server" Format="dd/MM" TargetControlID="TextBox1" />
    Tip 5: How to Set Culture to work with CalendarExtender
    Make sure that the ScriptManager has EnableScriptGlobalization="true" and EnableScriptLocalization="true".
    <asp:ScriptManager ID="ScriptManager1" runat="server"
             EnableScriptGlobalization="true" EnableScriptLocalization="true" />
    Tip 6: How to make sure user does not select a date earlier than today or greater than today
    There could be instances where you do not want the user to select a day earlier than the current date. For example: when you are providing the user a form to book tickets, you would not like him to choose an earlier date. To achieve this requirement, use the following javascript code.
    Prevent the User from selecting a Date Earlier than today
    <head runat="server">
        <title>Calendar Extender</title>
        <script type="text/javascript">
        function checkDate(sender,args)
    {
     if (sender._selectedDate < new Date())
                {
                    alert("You cannot select a day earlier than today!");
                    sender._selectedDate = new Date(); 
                    // set the date back to the current date
    sender._textbox.set_Value(sender._selectedDate.format(sender._format))
                }
    }
        </script>
    </head>
    Call the code:
       <form id="form1" runat="server">
            <asp:ScriptManager ID="ScriptManager1" runat="server" />
            <div>
              
                <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <cc1:CalendarExtender ID="CalendarExtender1"
                runat="server" OnClientDateSelectionChanged="checkDate" TargetControlID="TextBox1" />
            </div>
        </form>
    Select Date Greater than today
    In the javascript, just change this line
    sender._selectedDate > new Date()
    Note: You may argue that the user can still change the date by typing into the textbox or entering an invalid date. Well that can be easily handled using a ValidationControl and is covered in the next tip.
    Tip 7: Add validation to the CalendarExtender Control
    A simple way to add validation to the Calendar is to add a ValidationControl to the textbox associated with a CalendarExtender. You have two choices:
    A.  Add an ‘Extender’ to the ValidationControl. To do so, drag and drop a ValidationControl > click on the smart tag of the ValidationControl > choose ‘Add Extender’. From the Extender Wizard, choose ValidatorCalloutExtender. Using this approach makes it extremely easy to discover and attach control extenders to your controls. In VS 2005, you had to do this process manually, by wiring up control extenders.
    B.  You can choose not to add the Extender.
    We will go ahead with option A. We will be adding two ValidationControls to the textbox. The first, a CompareValidator to check if the user does not enter an invalid date (Eg: May 32) and second, a RangeValidator to keep the date range as desired.
    Adding CompareValidator
    <asp:CompareValidator ID="CompareValidator1" runat="server"
                    ControlToValidate="TextBox1" Display="Dynamic" ErrorMessage="Invalid Date"
                    Operator="DataTypeCheck" Type="Date">
    </asp:CompareValidator>
    <cc1:ValidatorCalloutExtender ID="CompareValidator1_ValidatorCalloutExtender"
                    runat="server" Enabled="True" TargetControlID="CompareValidator1">
    </cc1:ValidatorCalloutExtender>
    Adding RangeValidator – We will restrict the user to select a date range starting from today to 15 days from now.
    <asp:RangeValidator ID="RangeValidator1" runat="server"
                    ControlToValidate="TextBox1" ErrorMessage="RangeValidator"
                    Type="Date">
    </asp:RangeValidator>
    <cc1:ValidatorCalloutExtender ID="RangeValidator1_ValidatorCalloutExtender"
                    runat="server" Enabled="True" TargetControlID="RangeValidator1">
    </cc1:ValidatorCalloutExtender>
    In the code behind of your page, add this code
    C#
        protected void Page_Load(object sender, EventArgs e)
        {
            RangeValidator1.MinimumValue = System.DateTime.Now.ToShortDateString();
            RangeValidator1.MaximumValue = System.DateTime.Now.AddDays(15).ToShortDateString();
        }
    Tip 8: CalendarExtender Popup Window bring to front 
    When user selects a date form the Calendar Extender. In web page if there is any images bellow of the calendar extender control it will go behind of that image. To bring front we need to add the following script 
     function SetIndex(sender)
    {
     sender._popupDiv.style.zIndex=501;
    }
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <cc1:CalendarExtender ID="CalendarExtender1"
                runat="server" OnClientDateSelectionChanged="checkDate" OnClientShown="SetIndex" TargetControlID="TextBox1" />

    Well those were some tips associated with the CalendarExtender. As future versions of the toolkit are released, we should be hopeful that there will exist easier ways, of achieving the functionality discussed in this article. I hope this article was useful and I thank you for viewing it.

    20 November 2011

    What is the difference between Web Farm and Web Garden?

    Visual Studio has its own integrated ASP.NET engine which is used to run the ASP.NET Web application from Visual Studio. ASP.NET Development Server is responsible for executing all the requests and responses from the client. Now after the end of development, when you want to host the site on some server to allow other people to access, concept of web servers comes in between. A web server is responsible for providing the response for all the requests that are coming from clients. The below diagram shows the typical deployment structure of an ASP.NET Web application with a single IIS.



    Clients request for resources and IIS process the request and send back to clients.


    Web Farm


    This is the case where you have only one web server and multiple clients requesting for resources from the same server. But when are is huge amount of incoming traffic for your web sites, one standalone server is not sufficient to process the request. You may need to use multiple servers to host the application and divide the traffic among them. This is called “Web Farm”. So when you are hosting your single web site on multiple web servers over load balancer is called “Web Farm”. The below diagram shows the overall representation of Web Farms.


    In general web farm architecture, a single application is hosted on multiple IIS Server and those are connected with the VIP (Virtual IP) with Load Balancer. Load Balancer IPs are exposed to external world to access. So whenever some request will come to server from clients, it will first hit the Load Balancer, then based on the traffic on each server, LB distributes the request to the corresponding web server. These web servers may share the same DB server or may be they can use a replicated server in the back end.

    So, in a single statement, when we host a web application over multiple web servers to distribute the load among them, it is called Web Farm.

    Web Garden

    Now, let’s have a look at what is Web Garden? Both the terms sound the same, but they are totally different from each other. Before starting with Web Garden, I hope you have a fundamental idea of what an Application Pool is and what a Worker Process is.

    Just to recall, when we are talking about requesting processing within IIS, Worker Process (w3wp.exe) takes care of all of these. Worker Process runs the ASP.NET application in IIS. All the ASP.NET functionality inside IIS runs under the scope of worker process. Worker Process is responsible for handling all kinds of request, response, session data, cache data. Application Pool is the container of worker process. Application pool is used to separate sets of IIS worker processes and enables a better security, reliability, and availability for any web application.



    Now, by default, each and every Application pool contains a single worker process. Application which contains the multiple worker process is called “Web Garden”. Below is the typical diagram for a web garden application.

    In the above diagram, you can see one of the applications containing the multiple worker processes, which is now a web garden.

    So, a Web application hosted on multiple servers and access based on the load on servers is called Web Farms and when a single application pool contains multiple Worker processes, it is called a web garden.

    Create Web Garden in IIS 6 and IIS 7


    Now, I am going to show how you can change the Number of Worker processes in both IIS 6 and IIS 7. For IIS 6, Right Click on Application Pool > Properties > Goto Performance Tab.


    In the “Performance Tab” section, you would have one option called “Web Garden” where worker process sets to “1”, you can set the number of worker processes that you required.

    For IIS 7, Right Click on Application Pool > Go To Advance Settings > In Process Model section, you will have “Maximum Worker Processes”. You can change it more than 1 to make it as a web garden.
    In the above image, you can also check the definition of Web Garden.

    Advantages of Web Farm and Web Garden


    Now, let’s have a look into the advantages of both the Web Farms and Web Gardens.

    Advantages of Web Farm


    • It provides high availability. If any of the servers in the farm goes down, Load balancer can redirect the requests to other servers.
    • Provides high performance response for client requests.
    • Provides better scalability of the web application and reduces the failure of the application.
    • Session and other resources can be stored in a centralized location to access by all the servers.

    Advantages of Web Garden


    • Provides better application availability by sharing requests between multiple worker process.
    • Web garden uses processor affinity where application can be swapped out based on preference and tag setting.
    • Less consumption of physical space for web garden configuration.

    How to Manage Session in Web Farm Mode?


    While using session, requests are distributed among different servers. By default, session mode is set to In Proc where session data is stored inside worker process memory. But, in Web farm mode, we can share the session among all the servers using a single session store location by making it Out proc (State Server or SQL Server Mode). So, if some of the servers go down and request is transferred to the other server by the Load balancer, session data should be available for that request.
    In the above diagram, you can see that we can both the IIS server sharing the same session data which is stored in out of worker process. You can read one of my previous articles “Exploring Session in ASP.NET” where I have explained how you can configure session mode for Out Process mode.

    How to Manage Session in Web Garden Mode?


    When we are using Web garden where request is being taken care of by different worker process, we have to make the session mode as out process session mode as described earlier. For Web Garden, we have to configure the out process within the same server but for different worker process. 
    While using Web garden with your application, you need make a couple of configuration settings in web.config in <process Model> section where you need to set certain properties like cpuMask, RequestLimit, webGarden, ClientConnectCheck, etc.

    Summary


    When we host a web application over multiple web servers to distribute the load among them, it is called Web Farm and when one application has multiple worker processes, it is called a Web garden.