What is the difference between ‘classic’ and ‘integrated’ pipeline mode in IIS7?

Classic mode (the only mode in IIS6 and below) is a mode where IIS only works with ISAPI extensions and ISAPI filters directly. In fact, in this mode, ASP.NET is just an ISAPI extension (aspnet_isapi.dll) and an ISAPI filter (aspnet_filter.dll). IIS just treats ASP.NET as an external plugin implemented in ISAPI and works with it like a black box (and only when it’s needs to give out the request to ASP.NET). In this mode, ASP.NET is not much different from PHP or other technologies for IIS.

Integrated mode, on the other hand, is a new mode in IIS7 where IIS pipeline is tightly integrated (i.e. is just the same) as ASP.NET request pipeline. ASP.NET can see every request it wants to and manipulate things along the way. ASP.NET is no longer treated as an external plugin. It’s completely blended and integrated in IIS. In this mode, ASP.NET HttpModules basically have nearly as much power as an ISAPI filter would have had and ASP.NET HttpHandlers can have nearly equivalent capability as an ISAPI extension could have. In this mode, ASP.NET is basically a part of IIS.

Reference: Narendra Singh (http://blog.sikarnarender.com)

Formatting Numbers in ASP.Net

Formatting is the process of converting an instance of a class, structure, or enumeration value to its string representation. Anytime you display a DateTime or Numeric variables in an ASP.NET page, you are formatting that variable from its native type into some sort of string representation. How a DateTime or Numeric variable is formatted depends on the culture settings and the format string. Because dates and numeric values are formatted differently across cultures, the .NET Framework bases its formatting on the specified culture settings. By default, the formatting routines use the culture settings defined on the web server, but you can indicate that a particular culture be used anytime you format. In addition to the culture settings, formatting is also affected by a format string, which spells out the formatting details to apply.
There are a couple of different ways to format a DateTime or numeric variable. The first way involves using the ToString method, which has a number of overrides. Formatting can also be performed using the String.Format method. The String.Format method accepts as input a format string that contains a number of placeholders, followed by the values to plug into those placeholders. Placeholders take the form {0}, {1}, and so on, and may optional include a format string like so: {0:formatString}.The following code snippet shows using the String.Format method.

Dim CustName As String = “Narendra”
Dim subtotal as Decimal = 245.13
Dim output As String = String.Format(“{0}, your order subtotal is {1:c}.”, CustName, subtotal)

Standard Numeric Format String
Standard numeric format strings are used to format common numeric types. A standard numeric format string takes the form Axx, where A is an alphabetic character called the format specifier, and xx is an optional integer called the precision specifier. The precision specifier ranges from 0 to 99 and affects the number of digits in the result. Any numeric format string that contains more than one alphabetic character, including white space, is interpreted as a custom numeric format string.

Format Name Code snippet Output
1. Currency(“C” or “c”)
Result : A currency value.
Supported by : All numeric types.
Precision Specifier : Number of decimal digits.
123.ToString(“C”, New CultureInfo(“en-US”))
3.14159.ToString(“C2”, New CultureInfo(“en-US”))
$123.00
$3.14
2. Decimal(“D” or “d”)
Result : Integer digits with optional negative sign.
Supported by : Integral types only.
Precision Specifier : Minimum number of digits.
1234.ToString(“D”)
1234.ToString(“D6”)
1234
001234
3. Exponential(“E” or “e”)
Result : Exponential notation.
Supported by : All numeric types.
Precision Specifier : Number of decimal digits.
1052.0329112756.ToString(“E”, New CultureInfo(“en-US”))
1052.0329112756.ToString(“E2”, New CultureInfo(“en-US”))
1.052033E+003
1.05E+003
4. Fixed-point(“F” or “f”)
Result : Integral and decimal digits with optional negative sign.
Supported by : All numeric types.
Precision Specifier : Number of decimal digits.
1234.567.ToString(“F”, New CultureInfo(“en-US”))
1234.567.ToString(“F4”, New CultureInfo(“en-US”))
1234.57
1234.5670
5. General(“G” or “g”)
Result : The most compact of either fixed-point or scientific notation.
Supported by : All numeric types.
Precision Specifier : Number of significant digits.
123.4546.ToString(“G4”, New CultureInfo(“en-US”)) 123.5
6. Number(“N” or “n”)
Result : Integral and decimal digits, group separators, and a decimal separator with optional negative sign.
Supported by : All numeric types.
Precision Specifier : Desired number of decimal places.
1234.56712.ToString(“N”, New CultureInfo(“en-US”))
1234.56712.ToString(“N3”, New CultureInfo(“en-US”))
1,234.57
1,234.567
7. Percent(“P” or “p”)
Result : Number multiplied by 100 and displayed with a percent symbol.
Supported by : All numeric types.
Precision Specifier : Desired number of decimal places.
1.ToString(“P”, New CultureInfo(“en-US”))
12.56712.ToString(“P2”, New CultureInfo(“en-US”))
100.00 %
1,256.71 %
8. Round-trip(“R” or “r”)
Result : A string that can round-trip to an identical number.The round-trip (“R”) format specifier guarantees that a numeric value that is converted to a string will be parsed back into the same numeric value.
Supported by : Single, Double, and BigInteger.
Precision Specifier : Ignored.
3.14159.ToString(“R”, New CultureInfo(“en-US”)) 3.14159
9. Hexadecimal(“X” or “x”)
Result : A hexadecimal string.
Supported by : Integral types only.
Precision Specifier : Number of digits in the result string.
255.ToString(“X”, New CultureInfo(“en-US”))
255.ToString(“X4”, New CultureInfo(“en-US”))
FF
00FF

Custom Numeric Format String
If the standard numeric format specifiers do not provide the type of formatting you require, you can use custom format strings to further enhance string output. A standard format string consists of a single alphabetic character optionally followed by a sequence of digits that form a value between 0 and 99; all other format strings are custom format strings.
The following table shows the characters you can use to create custom numeric format strings and their definitions.

Format Name Code snippet Output
1. Zero placeholder(0)
Description : If the value being formatted has a digit in the position where the
‘0’ appears in the format string, then that digit is copied to the result string.
The position of the leftmost ‘0’ before the decimal point and the rightmost ‘0’
after the decimal point determines the range of digits that are always present in
the result string.
3.14.ToString(“00.0000”, New CultureInfo(“en-US”))
123.45678.ToString(“00.0000”, New CultureInfo(“en-US”))
03.1400
123.4568
2. Digit placeholder(#)
Description : If the value being formatted has a digit in the position where the
‘#’ appears in the format string, then that digit is copied to the result string.
Otherwise, nothing is stored in that position in the result string.
3.14.ToString(“#0.000#”, New CultureInfo(“en-US”))
123.45678.ToString(“#0.000#”, New CultureInfo(“en-US”))
3.140
123.4568
3. Decimal point(.)
Description : The first ‘.’ character in the format string determines the location
of the decimal separator in the formatted value; any additional ‘.’ characters are
ignored.
123.446.ToString(“#####.#”, New CultureInfo(“en-US”))
12345.6.ToString(“####.##”, New CultureInfo(“en-US”))
123.4
12345.6
4. Thousand separator(,)
Description : If the format string contains a ‘,’ character between two placeholders
(0 or #), then the output will have thousand separators inserted between each group
of three digits to the left of the decimal separator.
123456.ToString(“#,000.00”, New CultureInfo(“en-US”)) 123,456.0
5. Number scaling(,)
Description : If the format string contains one or more ‘,’ characters immediately
to the left of the decimal point, then the number will be divided by the number
of ‘,’ characters multiplied by 1000 before it is formatted.
2000000.ToString(“0,,”, New CultureInfo(“en-US”))
2000000.ToString(“0,”, New CultureInfo(“en-US”))
2
2000
6. Percentage placeholder(%)
Description : The presence of a ‘%’ character in a format string causes a number
to be multiplied by 100 before it is formatted. The appropriate symbol is inserted
in the number itself at the location where the ‘%’ appears in the format string.
0.086.ToString(“#0.##%”, New CultureInfo(“en-US”))
0.086.ToString(“#0%.##”, New CultureInfo(“en-US”))
8.6%
8%.6
7. Scientific notation(E0,E+0,E-0,e0,e+0,e-0)
Description : If any of the strings “E”, “E+”, “E-“, “e”, “e+”, or “e-” are present
in the format string and are followed immediately by at least one ‘0’ character,
then the number is formatted using scientific notation with an ‘E’ or ‘e’ inserted
between the number and the exponent. The number of ‘0’ characters following the
scientific notation indicator determines the minimum number of digits to output
for the exponent. The “E+” and “e+” formats indicate that a sign character (plus
or minus) should always precede the exponent. The “E”, “E-“, “e”, or “e-” formats
indicate that a sign character should only precede negative exponents.
86000.ToString(“0.###E+0”, New CultureInfo(“en-US”))
86000.ToString(“0.###E+000”, New CultureInfo(“en-US”))
86000.ToString(“0.###E-000”, New CultureInfo(“en-US”))
8.6E+4
8.6E+004
8.6E004
8. Section separator(;)
Description : The ‘;’ character is used to separate sections for positive, negative,
and zero numbers in the format string.
1234.ToString(“##;(##)”, New CultureInfo(“en-US”))
-1234.ToString(“##;(##)”, New CultureInfo(“en-US”))
1234
(1234)

Select distinct record from datatable, vb.net

Recently i shared my ideas on How to merge and sort two datatables. Completition of this task raise an another issue to Select distinct record from the merged datatable. I found many lengthy process but these are not ok. After some goggling i found a very easy process. Just create a dataview object of the datatable and

dt = dt.DefaultView.ToTable(true, param)

Where param will hold the Column Name for which you want to make distinct values.
So there is no need for any change in How to merge and sort two datatables process, we will just update the code on return statement of the function.

Private Function MergeAndSortTables(ByVal Table1 As DataTable, ByVal Table2 As DataTable, ByVal SortBy As String) As DataTable
  Table1.Merge(Table2)
  Dim View As DataView = Table1.DefaultView
  View.Sort = SortBy

  Return View.ToTable(true)
End Function

It’s funny….

How to merge & sort two datatables

There is two datatables with same column & would like to append one of these datatables on to the end of the other. You may use following code :

Private Function MergeAndSortTables(ByVal Table1 As DataTable, ByVal Table2 As DataTable, ByVal SortBy As String) As DataTable
  Table1.Merge(Table2)
  Dim View As DataView = Table1.DefaultView
  View.Sort = SortBy

  Return View.ToTable()
End Function

Assembly in Asp.Net

An assembly is a logical unit of code. It physically exists as DLLs or EXEs. One assembly can contain one or more files like image files, text files etc. along with DLLs or EXEs.
Assemblies in the .Net platform are a solution to a problem that has been around as long as libraries. The problem knows as “DLL Hell”, can be caused by one application overwriting a shared library of another application, usually with a different version.
Imagine you write an application with a shared library and then years later create a new application with an updated library. In order not to break old programs, what do you do with the new library? You could give it a different name, store it in a different location, or overwrite the old ones?
.Net assemblies overcome these issues by storing information about themselves, rather than having that information stored in central location (i.e. system registry). This information is called as Assembly Manifest.
Assembly manifest

  • Assembly manifest is a data structure which stores information about an assembly.
  • This information is stored within the assembly file itself.
  • The information includes version information, list of constituent files etc.

What is in the Assembly?
The assembly contains the intermediate code, resources, and the metadata for itself. We can have a look inside the assembly using the ildasm (Intermediate Language Disassembler) tool that comes as part of Visual Studio. To access it you need to open the Visual Studio Command Prompt and type ildasm.exe. To open the Visual Studio Command Prompt goes to:
Start>All Program>Microsoft Visual Studio 2010>Visual Studio Tools>Visual Studio Command Prompt (2010)

Visual Studio Command Prompt
Figure 1: Visual Studio Command Prompt

This will launch a window application that you can use to explore any .Net application. Once launched, you can open any .Net application (File>Open) and view information within the file, including the manifest, types, classes, namespaces, methods and source code.
Visual Studio Command Prompt
Figure 2: Intermediate Language Disassembler

Assembly Types
You can create two types of ASP.Net Assemblies: Private Assemblies and Shared Assemblies.
The assembly which is used only by a single application is called as private assembly. Suppose you created a DLL which encapsulates your business logic. This DLL will be used by your client application only and not by any other application. In order to run the application properly your DLL must reside in the same folder in which the client application is installed. Thus the assembly is private to your application.
Suppose that you are creating a general purpose DLL which provides functionality which will be used by variety of applications. Now instead of each client application having its own copy of DLL you can place the DLL in ‘Global Assembly Cache’. Such assemblies are called shared assemblies.
Creating a Shared Assembly
The procedure for creating a shared assembly is the same as for a private assembly, except that there are a few extra steps involved before you can use it. All shared assemblies need to be strongly named before they can be installed into the global assembly cache. Strongly named assemblies ensure that the assembly has unique manifest consisting of versioning information and public key.
Steps to create shared assemblies:

  • Create your DLL source code.
  • Generate unique assembly name using SN utility.
  • Sign your DLL with the private key by modifying AssemblyInfo file.
  • Compile your DLL.
  • Place the resultant DLL in global assembly cache using GACUtil utility.

What is Global Assembly Cache?
Global Assembly Cache is nothing but a special disk folder where all the shared assemblies will be kept. It is located under :\WinNT\Assembly Folder.
If you are using .Net framework 4.0 then the folder will be : :\WinNT\Microsoft.Net\Assembly.
How do I create unique assembly name?
Microsoft now uses a public-private key pair to uniquely identify an assembly. To generate this cryptographic key pair, use the SN Tool. Go to Visual studio command prompt and use the following syntax to generate a key file.

sn -k “[DriveLetter]:\[DirectoryToPlaceKeyFile]\[KeyFileName].snk”
e.g. sn -k “C:\GACKey\GACkey.snk”

How do I sign my Assembly?
A key is generated, but it is not yet associated with the assembly of the project. To create this association, double-click the AssemblyInfo.vb file in Visual Studio .NET Solution Explorer. This file has the list of assembly attributes that are included by default when a project is created in Visual Studio .NET.
Modify the AssemblyInfo.vb by adding the following AssemblyKeyFile attribute:

[Assembly: AssemblyKeyFile(“C:\\GACKey\\GACKey.snk”)]

How do I place the assembly in shared cache?
You can install the .dll file by using the Gacutil tool or by dragging the .dll file to the appropriate folder. If you use the Gacutil tool, you can use a command that resembles the following:

gacutil -I “[DriveLetter]:\[DirectoryOfDllFile]\[dll File]”

To drag the file, open two instances of Windows Explorer. In one instance, find the location of the .dll file output for your console project. In the other instance, find WinNT\Assembly. Then, drag your .dll file to the Assembly folder.
Hands On…
Now, that we have understood the basics of assemblies let us apply our knowledge by developing a simple shared assembly.
In this example we will create a VB.NET component called SharedAssembly. We will also create a key file named sample.snk. We will sign our component with this key file and place it in Global Assembly Cache.
Step 1: Creating our sample component
Here is the code for the component. It just includes one method which returns a string “Hello World”.

Namespace SharedAssembly
  Public Class Test
    Public Function Helloworld() As String
      Return “Hello World”
    End Function
  End Class
End Namespace

Visual Studio Command Prompt
Figure 3: VB.Net Class File

Step 2: Generate a key file
To generate the key file use the following command at visual studio command prompt:

SN –k c:\sample.snk

Visual Studio Command Prompt
Figure 4 : Generate Key File

Step 3: Sign your component with the key file
To sign the component add the following AssemblyKeyFile attribute in AssemblyInfo.vb file:

[Assembly: AssemblyKeyFile(“C:\\sample.snk”)]

Visual Studio Command Prompt
Figue 5 : AssemblyInfo.vb

Step 4: Host the signed assembly in Global Assembly Cache
To install the assembly in Global Assembly Cache we will use GACUtil Tool. Go to Visual studio command prompt, use the following code :

gacutil –i D:\Test\sikarnarender.com\Assembly\SharedAssembly
\SharedAssembly\bin\Debug\SharedAssembly.dll

Visual Studio Command Prompt
Figure 6: GACUtil.exe

After hosting the assembly just goes to WINNT\Assembly folder and you will find your assembly listed there.

State Management with Context.Items, Asp.net

Passing values between pages is a common task in every asp.net web application.There are many options for state management including Session, Cookies, QueryString etc. Each of these have their strength and weakness and each is designed for different circumstances, it just depends of your requirement. This article will focus on the use of context.items collection to pass variable between different pages.

Assume we have a ecommerce site, the page “ProductList” shows the list of products.When I click on a product, it will redirect the user to “ProductDescription”. How do I tell “ProductDescription” which product to show ?

One possible approach is to use the QueryString and pass the ProductId to the “ProductDescription” page as shown in listing 1 and 2.

Response.Redirect(“ProductDescription.aspx?PrdId=2”)

Listing 1: “ProductList” using the QueryString

Dim PrdId as Integer=Request.QueryString(“PrdId”)

Listing 2: “ProductDescription” using the QueryString

The above approach is totally acceptable. There are several disadvantages of this approach, some of which are as follows:

  • The QueryString is exposed with the URL meaning sensitive data may be revealed.
  • The length of the QueryString is generally limited (e.g. 256 bytes in IE).
  • The QueryString can only contain character data (no objects).
  • Response.Redirect requires a round trip from server to client to server.

A better approach is to store the Product Id in Context.Items collection, then use server.transfer to redirect to the “ProductDescription” as shown in listing 3 and 4.

Context.Items.Add(“PrdId”,2)
Server.Transfer(“ProductDescription.aspx”)

Listing 3: “ProductList” using the Context.Items collection

Dim PrdId as Integer=Context.Items.Item(“PrdId”)

Listing 4: “ProductDescription” using the Context.Items collection

Server.Transfer performs a server-side redirect that is transparent to the user, meaning there is no need of a round trip.The Context.Items collection is also capable of storing objects instead of just plain character data.

It is important to keep in mind that values stored in the Context.Items collection only last for the current request. If I were to do a postback on the “ProductDescription” page, the Context item “Id” would be lost. Most of the time this is convienient since we only need to store that value between pages and no longer.

Viewstate collection is the solution to retain the values between postbacks.

Callback Combo on Scroll down

You can grab the external JavaScript file representing the jQuery library need for this sample from either of these URLs  – 
http://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js

You have to create two folders as images : to hold the images 1.)dropdown_arrow.gif  2.) spinner.gif and the second folder will be as js : to hold the jquery file.

Onto the code …


CallbackAsyncHandler.ashx : It has all logics to fetch records from database on the bahalf of parameters defined on user control.  It receives all parameter using query string.

<%@ WebHandler Language=”VB” Class=”CallbackAsyncHandler” %>


Imports System.Web
Imports System.Text
Imports System.Data
Imports System.Data.SqlClient


Public Class CallbackAsyncHandler
Implements IHttpHandler


Public Sub ProcessRequest(context As HttpContext) Implements IHttpHandler.ProcessRequest
        Dim Condition As String = Convert.ToString(context.Request.QueryString(“Condition”)).Replace(“#”, “+”)
        Dim CCondition As String = Convert.ToString(context.Request.QueryString(“CCondition”)).Replace(“#”, “+”)
        Dim ValueField As String = Convert.ToString(context.Request.QueryString(“ValueField”)).Replace(“#”, “+”)
        Dim TextField As String = Convert.ToString(context.Request.QueryString(“TextField”)).Replace(“#”, “+”)
        Dim TableName As String = Convert.ToString(context.Request.QueryString(“TableName”)).Replace(“#”, “+”)
        Dim BunchSize As Integer = Convert.ToString(context.Request.QueryString(“BunchSize”)).Replace(“#”, “+”)
        Dim OrderBy As String = Convert.ToString(context.Request.QueryString(“OrderBy”)).Replace(“#”, “+”)
        
        If OrderBy = 1 Then
            OrderBy = ValueField
        Else
            OrderBy = TextField
        End If


        context.Response.Write(PrepareDataSet(Condition, ValueField, TextField, TableName, BunchSize, CCondition, OrderBy))
End Sub


    Private Function PrepareDataSet(ByVal Condition As String, ByVal ValueField As String, ByVal TextField As String, _
                                    ByVal TableName As String, ByVal BunchSize As Integer, ByVal CCondition As String, ByVal OrderBy As String) As String
        
        ‘New SqlConnection(“Data Source=pankajpareek;Initial Catalog=T480;User ID=sa;Password=redtray”)
        Dim conn As System.Data.SqlClient.SqlConnection = New SqlConnection(System.Configuration.ConfigurationManager.AppSettings(“connection”))
        Dim strSql As String = “Select TOP ” & BunchSize & ” ” & ValueField & “,” _
                            & TextField & ” From ” & TableName & ” Where 1=1 ” & CCondition & Condition & ” Order by ” & OrderBy
        Dim da As SqlDataAdapter = New System.Data.SqlClient.SqlDataAdapter(strSql, conn)
        Dim dt As New DataTable
        da.Fill(dt)


        Return BuildRows(dt)
    End Function


Private Function BuildRows(dt As System.Data.DataTable) As String
Dim sb As New StringBuilder()
Dim dr As System.Data.DataRow
If dt.Rows.Count > 0 Then
For i As Integer = 0 To dt.Rows.Count – 1
sb.Append(“<tr class=’mouseOut’ onmouseover=’mouseOver(this)’ onmouseout=’mouseOut(this)’ onclick=’Select(this)’ ctype=’CallbackCombo’>”)
dr = dt.Rows(i)
For j As Integer = 0 To dt.Columns.Count – 1
If j = 0 Then
sb.Append(“<td class=’displayNone’>” & Convert.ToString(dr(j)) & “</td>”)
Else
sb.Append(“<td>” & Convert.ToString(dr(j)) & “</td>”)
End If
Next
sb.Append(“</tr>”)
Next
End If
Return sb.ToString()
End Function


Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class

CallbackCombo.ascx : It keeps all the design & javacript logic. On Vb side it has all property & variables used to define Callback Combo dynamically.

Design View

<%@ Control Language=”VB” AutoEventWireup=”false” CodeFile=”CallbackCombo.ascx.vb”
    Inherits=”CallbackCombo_CallbackCombo” %>
<asp:Literal ID=”Literal1″ runat=”server”>
</asp:Literal>


<script type=”text/javascript”>
        var prev = 0;
        var ValueField=”<%=ValueField %>”;
        var TextField=”<%=TextField %>”;
        var TableName=”<%=TableName %>”;
        var BunchSize=”<%=BunchSize %>”;
        var OrderBy=”<%=OrderBy %>”;
        var CCondition=”<%=Condition %>”;
        var FolderPath=”<%=FolderPath %>”;
        var DefaultText=”<%=DefaultText %>”;
        var DefaultValue=”<%=DefaultValue %>”;
        
        $(document).ready(
            function() 
            {
                $(“.divProgress”).hide();
                $(“#ImgDropDown”).attr(“src”, FolderPath + “/images/dropdown_arrow.gif”);
                $(“#imgProgress”).attr(“src”, FolderPath + “/images/spinner.gif”);
                
                $(document).click
                (
                    function()
                    {
                        var obj=window.event.srcElement;
                        if($(obj).attr(“ctype”)!=”CallbackCombo”)
                        {
                            ComboListShow=0;
                            $(“#divList”).slideUp(“fast”);
                        }                       
                    }
                )


                $(“#divList”).scroll
                (
                    function() 
                    {
                        if ($(“#tblList”)[0].clientHeight – this.scrollTop == $(this)[0].clientHeight) 
                        {
                            var LastId = $(“#tblList tr:last”).children(“td:first”).html();
                            var trLast = $(“#tblList tr:last”);
                            if (parseInt(LastId, 10) > parseInt(prev, 10)) 
                            {
                                prev = LastId;
                                appendData(” And ” + TextField + ” like ‘” + $(“#” + “<%=txtInput.ClientId %>”).val() + “%’ And ” + ValueField + “>” + LastId);
                            }
                        }
                    }
                );
            }
        );
        function appendData(condition)
        {
            $(“.divProgress”).ajaxStart(function() {
                 $(this).show();
            });
             $(“.divProgress”).ajaxStop(function() {
                 $(this).hide();
            });
            $.post(FolderPath + “/CallbackAsyncHandler.ashx?ValueField=” + escape(ValueField) + “&TextField=” + escape(TextField) + “&TableName=” + escape(TableName)
                                            + “&BunchSize=” + escape(BunchSize) + “&CCondition=” + escape(CCondition) + “&OrderBy=” + escape(OrderBy) 
                                            + “&Condition=” + escape(condition), function(data) {
                 if (data != null && data!=””) 
                 {
                    if($(‘#tblList tr’).length<=0 && DefaultText!=””)
                    {
                        var Temp=”<tr class=’mouseOut’ onmouseover=’mouseOver(this)’ onmouseout=’mouseOut(this)’ onclick=’Select(this)’ ctype=’CallbackCombo’>”;
                        if(DefaultValue!=””)
                        {
                            Temp=Temp + “<td class=’displayNone’>” + DefaultValue + “</td>”
                        }
                        else
                        {
                            Temp=Temp + “<td class=’displayNone’>” + DefaultText + “</td>”
                        }
                        Temp=Temp + “<td>” + DefaultText +  “</td>”;
                        Temp=Temp + “</tr>”
                        $(“#tblList”).append(Temp);
                    }
                    $(“#tblList”).append(data);
                }
            });
        }
</script>


<script type=”text/javascript”>
        var ComboListShow=0;
        function ShowList()
        {
            if(ComboListShow==1)
            {
                ComboListShow=0;
                $(“#divList”).slideUp(“fast”);
            }
            else
            {
                var UserIdLast = 0;                
                if($(‘#tblList tr’).length<=0)
                {
                    appendData(” And ” + TextField + ” like ‘” + $(“#” + “<%=txtInput.ClientId %>”).val() + “%’ And ” + ValueField + “>0”);
                }
                $(“#divList”).slideDown(“fast”);
                if ($(“#tblList tr.trselect”).length>0)
                {
                    //$(“#divList”).animate({ scrollTop: $(“#tblList tr.trselect”)[0].offsetTop-(14*17) }, “slow”)
                    $(“#divList”).scrollTop($(“#tblList tr.trselect”)[0].offsetTop-(14*17))
                }
                ComboListShow=1;
            }
        }
        function filter()
        {
            prev=0;
            $(“#tblList tr”).remove();
            $(“#” + “<%=hdnValue.ClientId %>”).val(‘0’);
            appendData(” And ” + TextField + ” like ‘” + $(“#” + “<%=txtInput.ClientId %>”).val() + “%’ And ” + ValueField + “>0”);
            $(“#divList”).slideDown(“fast”);
            ComboListShow=1;
        }
        function RemoveCallbackComboRow()
        {
            $(“#tblList tr”).remove();
            $(“#” + “<%=txtInput.ClientId %>”).val(”);
            $(“#” + “<%=hdnValue.ClientId %>”).val(‘0’);
        }
</script>


<style type=”text/css”>
    .dvInput
    {
        border: solid 1px #8AA8FF;
        width: 200px;
        height: 20px;
    }
    .ImgDropDown
    {
        vertical-align: middle;
        width: 13px;
        height: 13px;
        float: right;
        margin-top: 3px;
        cursor: pointer;
    }
    .txtInput
    {
        width: 185px;
        border: none 0px #8AA8FF;
        height: 18px;
    }
    .divList
    {
        height: 200px;
        border: solid 1px #8AA8FF;
        border-top: solid 0px #8AA8FF;
        width: 200px;
        text-align: left;
        overflow-y: auto;
        overflow-x: auto;
    }
    .displayNone
    {
        display: none;
    }
    .divProgress
    {
        width: 100%; /*background-color: red;
            color: white;*/
    }
    .trmouseOver
    {
        background-color: Blue;
        color: White;
    }
    .trmouseOut
    {
        background-color: White;
        color: Black;
    }
    .trselect
    {
        background-color: Blue;
        color: White;
    }
</style>


<script type=”text/javascript” language=”javascript”>
        function mouseOver(Row)
        {
            $(“#tblList tr.trmouseOver”).removeClass(“trmouseOver”).addClass(“trmouseOut”);
            $(Row).removeClass(“trmouseOut”).addClass(“trmouseOver”);
        }
        function mouseOut(Row)
        {
            $(Row).removeClass(“trmouseOver”).addClass(“trmouseOut”);
        }
        function Select(Row)
        {
            $(“#” + “<%=txtInput.ClientId %>”).val($(Row).children(“td:last”).html());
            $(“#” + “<%=hdnValue.ClientId %>”).val($(Row).children(“td:first”).html());
            $(“#tblList tr”).removeClass(“trselect”).addClass(“trmouseOut”);
            $(Row).removeClass(“trmouseOut”).removeClass(“trmouseOver”).addClass(“trselect”);
        }
</script>


<div id=”CallbackCombo” runat=”server” style=”width: auto; height: auto;”>
    <div id=”dvInput” class=”dvInput” ctype=’CallbackCombo’>
        <img id=”ImgDropDown” alt=”” src=”images/dropdown_arrow.gif” class=”ImgDropDown”
            onclick=”ShowList()” ctype=’CallbackCombo’ />
        <asp:TextBox ID=”txtInput” runat=”server” CssClass=”txtInput” ctype=’CallbackCombo’
            onkeyup=”filter()”></asp:TextBox>
        <asp:HiddenField ID=”hdnValue” runat=”server” />
    </div>
    <div class=”divList” id=”divList” style=”display: none; position: absolute; z-index: 1000;
        background-color: White;” ctype=’CallbackCombo’>
        <table id=”tblList” style=”width: 90%; font-family: Arial; font-size: 12px;” ctype=’CallbackCombo’>
        </table>
        <div id=”loading” class=”divProgress” style=”width: 100%”>
            <center>
                <img src=”images/spinner.gif” id=”imgProgress” border=”0″></center>
        </div>
    </div>
</div>

Code View : 
Partial Class CallbackCombo_CallbackCombo
    Inherits System.Web.UI.UserControl


    Private _ValueField As String
    Private _TextField As String
    Private _TableName As String
    Private _BunchSize As Integer
    Private _FolderPath As String
    Private _Condition As String
    Private _OrderBy As OrderByType
    Private _DefaultText As String
    Private _DefaultValue As String


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Literal1.Text = “<script src='” & FolderPath & “/js/jquery-1.2.6.min.js’ type=’text/javascript’></script>”
    End Sub


    Public Property DefaultValue() As String
        Get
            Return _DefaultValue
        End Get
        Set(ByVal value As String)
            _DefaultValue = value
        End Set
    End Property


    Public Property DefaultText() As String
        Get
            Return _DefaultText
        End Get
        Set(ByVal value As String)
            _DefaultText = value
        End Set
    End Property


    Public Property ValueField() As String
        Get
            Return _ValueField
        End Get
        Set(ByVal value As String)
            _ValueField = value
        End Set
    End Property


    Public Property TextField() As String
        Get
            Return _TextField
        End Get
        Set(ByVal value As String)
            _TextField = value
        End Set
    End Property


    Public Property TableName() As String
        Get
            Return _TableName
        End Get
        Set(ByVal value As String)
            _TableName = value
        End Set
    End Property


    Public Property BunchSize() As Integer
        Get
            Return _BunchSize
        End Get
        Set(ByVal value As Integer)
            _BunchSize = value
        End Set
    End Property


    Public Property FolderPath() As String
        Get
            Return _FolderPath
        End Get
        Set(ByVal value As String)
            _FolderPath = value
        End Set
    End Property


    Public Property OrderBy() As OrderByType
        Get
            Return _OrderBy
        End Get
        Set(ByVal value As OrderByType)
            _OrderBy = value
        End Set
    End Property


    Public Property Condition() As String
        Get
            Return _Condition
        End Get
        Set(ByVal value As String)
            _Condition = value
        End Set
    End Property


    Public ReadOnly Property SelectedText() As String
        Get
            Return txtInput.Text
        End Get
    End Property


    Public ReadOnly Property SelectedValue() As String
        Get
            Return hdnValue.Value
        End Get
    End Property


    Public Enum OrderByType
        TextField = 0
        ValueField = 1
    End Enum


End Class

References : 
Load Content While Scrolling With jQuery
Implementing infinite scrolling with jQuery


Progressive loading in Gridview on Scroll down

In contrast to the Pagination patterns, the Continuous Scrolling pattern has no natural break. When using pagination patterns, a decision to only show a subset of data at a time and then let the user request more data if wanted is chosen. With the Continuous Scrolling, new data is automatically retrieved as the user has scrolled to the bottom of the page. It thus appears as if the page has no end, as more data will be loaded and inserted into the page each time the user scrolls to the bottom of page.


The minimalistic code sample explained here will show how to fetch records asynchronously on scrolling from a hypothetical Users table after the first batch is initially fetched. A Generic Handler (which is similar to an ASPX page but lacks HTML tags) is used to retrieve records asynchronously and hand it over to the parent page. So the sample basically consists of  the following 2 files which you will have to copy to a ASP.NET 2.0 Website in VS.NET 2005 or VS.NET 2008 –
FetchOnDemand.aspx
AsyncHandler.ashx

All the JavaScript magic to track when the user reaches the end of the scroll bar (in this example we simulate DIV scrolling  by restricting it’s height & setting overflow:auto style for the DIV tag) is done effortlessly by jQuery.

You can grab the external JavaScript file representing the jQuery library need for this sample from either of these URLs  –
http://code.jquery.com/jquery-latest.js
http://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js

You can copy and place the external JavaScript file in a JS folder under the ASP.NET 2.0 website you create in VS.NET for running this code sample or you may even choose to reference it directly in the code. The jQuery library will be used in the parent page (FetchOnDemand.aspx) to trigger fetching of new records dynamically on scrolling to the bottom. The parent page communicates the unique Id related to the last row that was previously fetched to a Generic Handler (AsyncHandler.ashx). The Handler in turn returns a batch of new records asynchronously as a HTML table so that it can be injected at the end of table rendered by the GridView in the parent page.

Onto the code …


FetchOnDemand.aspx displays the first 20 records through a GridView. jQuery helps us get the last User Id from the last row of the table rendered from the GridView. We pass this as parameter to the Generic Handler’s querystring -“AsyncHandler.ashx?lastUserId=

Design View :
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”FetchOnDemand.aspx.cs” Inherits=”FetchOnDemand” %>


<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
    <title>Untitled Page</title>
    <style type=”text/css”>
        body
        {
            font-family: Verdana, Arial, Helvetica, sans-serif;
            font-size: 11px;
            color: #666666;
        }
        .divLeft
        {
            height: 500px;
            border: solid 1px black;
            width: 1300px;
            text-align: left;
            overflow: auto;
        }
        .divProgress
        {
            width: 100%;
            /*background-color: red;
            color: white;*/
        }
        .tblHeader
        {
            font-weight: bold;
            text-align: left;
            background-color: gray;
            color: black;
        }
        td
        {
            text-align: center;
        }
    </style>


    <script src=”js/jquery-1.2.6.min.js” type=”text/javascript”></script>


    <script type=”text/javascript”>
            //following code utilizes jQuery 1.2.6
            var prev = 0;
             $(document).ready(
             
             //DIV showing the message “Loading…” is hidden initially
            //The message will be shown when records are fetched with AJAX 
            //when user has scrolled to the bottom of the DIV scrollbar 
            function() {
                 $(“.divProgress”).hide();


                 $(window).scroll(
                
            function() {
            //triggering point is when the difference of the heights of the TABLE 
            //and DIV match the DIV’s scrollTop value
            //if ($(“#tblOrders”).height() – ($(window).scrollTop()-50) == $(window).height()) {
            if ($(window).scrollTop() == $(document).height() – $(window).height()){
            //progress bar         
            $(“.divProgress”).ajaxStart(function() {
                 $(this).show();
            });
             $(“.divProgress”).ajaxStop(function() {
                 $(this).hide();
            });


            //get last Order Id to track next fetch
            var UserIdLast = $(“#tblOrders tr:last”).children(“td:first”).html();


            //get last table row in order to append the new result set increment
            var trLast = $(“#tblOrders tr:last”);
            if (parseInt(UserIdLast, 10) > parseInt(prev, 10)) {
                prev = UserIdLast;
                 //make a async call to fetch the incremental results     
                $.post(“AsyncHandler.ashx?lastUserId=” + UserIdLast, function(data) {
                     if (data != null) {
                         //append new result set to last row
                        trLast.after(data);
                    }
                });
            }
        }
    });
    });
    </script>


</head>
<body>
    <h3>
        This is a demo to show Continous Scrolling UI Pattern</h3>
    <form id=”form1″ runat=”server”>
    <%–<div class=”divLeft”>
    </div>–%>
    <asp:GridView ID=”tblOrders” runat=”server” AutoGenerateColumns=”false” CellPadding=”2″
        Width=”100%”>
        <HeaderStyle CssClass=”tblHeader” />
        <Columns>
            <asp:BoundField DataField=”UserID” HeaderText=”UserID” InsertVisible=”False” ReadOnly=”True”
                SortExpression=”UserID”></asp:BoundField>
            <asp:BoundField DataField=”LoginName” HeaderText=”LoginName” SortExpression=”LoginName”>
            </asp:BoundField>
            <asp:BoundField DataField=”FirstName” HeaderText=”FirstName” SortExpression=”FirstName”>
            </asp:BoundField>
            <asp:BoundField DataField=”LastName” HeaderText=”LastName” SortExpression=”LastName”>
            </asp:BoundField>
            <asp:BoundField DataField=”EmailAddress” HeaderText=”EmailAddress” SortExpression=”EmailAddress”>
            </asp:BoundField>
            <asp:BoundField DataField=”TelephoneNo” HeaderText=”TelephoneNo” SortExpression=”TelephoneNo”>
                <ItemStyle Width=”50px” />
            </asp:BoundField>
        </Columns>
    </asp:GridView>
    <div class=”divProgress”>
        Loading….
    </div>
    </form>
</body>
</html>

Code View : 
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;

public partial class FetchOnDemand : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        SqlConnection con=new SqlConnection(“ConnectionString”);
        string strSql = “Select TOP 20          UserId,LoginName,FirstName,LastName,EmailAddress,TelephoneNo From Users”;
        SqlDataAdapter dap= new SqlDataAdapter(strSql, con);
        DataTable dt=new DataTable();
        dap.Fill(dt);

        tblOrders.DataSource = dt;
        tblOrders.DataBind();
    }
}

AsyncHandler.ashx keeps the weight of the response lighter than an equivalent ASPX page. It takes a UserId value & returns the next twenty  records formatted in a HTML table so that it can be readily appended to the table in the parent view containing the bigger set of records.

 

<%@ WebHandler Language=”C#” Class=”AsyncHandler” %>


using System;
using System.Web;
using System.Text;
using System.Data;
using System.Data.SqlClient;


public class AsyncHandler : IHttpHandler
{
    
    public void ProcessRequest (HttpContext context) 
    { 
        //REMOVE BELOW LINE if you are using it in a real application 
        //It is here to simulate the delay while fetching results
        System.Threading.Thread.Sleep(2000);


        //The last OrderId is used to get the next increment
        string lastUserId = Convert.ToString(context.Request.QueryString[“lastUserId”]);


        //The PrepareDataSet method stuffs the DataSet into a HTML table 
        context.Response.Write(PrepareDataSet(lastUserId));
    }

    private string PrepareDataSet(string _UserId) 
    { 
        System.Data.SqlClient.SqlConnection conn = new SqlConnection(“ConnectionString”); 
        string strSql = “Select TOP 20 UserId,LoginName,FirstName,LastName,EmailAddress,TelephoneNo From Users Where UserId >” + _UserId;
        SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(strSql,conn); 
        DataSet ds = new System.Data.DataSet(); 
        da.Fill(ds, “Users”); 


        //The BuildRows method prepares a HTML table & stuffs the resultset into it 
        return BuildRows(ds.Tables[0]);
    }
     
    private string BuildRows(System.Data.DataTable dt) 
    { 
        StringBuilder sb = new StringBuilder();
        System.Data.DataRow dr; 
        if (dt.Rows.Count > 0) 
        { 
            for (int i = 0; i < dt.Rows.Count;i++) 
            { 
                sb.Append(“<tr class=’tblRow’>”); 
                dr = dt.Rows[i]; 
                for (int j = 0; j < dt.Columns.Count; j++) 
                { 
                    sb.Append(“<td>” + dr[j] + “</td>”); 
                } 
                sb.Append(“</tr>”); 
            } 
        } 
        return sb.ToString(); 
    } 


    public bool IsReusable 
    { 
        get 
        { 
            return false; 
        } 
    }
}

References : 
Load Content While Scrolling With jQuery
Implementing infinite scrolling with jQuery