Wednesday, July 30, 2008

This is ultimate grid from etcjs.com site a totally javascript grid which makes your site too fast you can't imagine...

This is ultimate grid from etcjs.com site a totally javascript grid which makes your site too fast you can't imagine...
=======================================================

Register this .js files and .css files for this grid display and work
===================================










ASCX control
============

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="DashBoardOrder.ascx.cs" Inherits="ascx_controls_DashBoardOrder" %>



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

dashboard.aspx.cs file
=====================




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.Text;

public partial class ascx_controls_DashBoardOrder : System.Web.UI.UserControl
{
#region Variable
private int _OrderType;
public string Details;
#endregion

#region Property
public int OrderType
{
get { return _OrderType; }
set { _OrderType = value; }
}
#endregion

#region PageLoad
protected void Page_Load(object sender, EventArgs e)
{


DataTable dt_Orders = DAL.Order.GetDashboardOrder(_OrderType);

StringBuilder sb = new StringBuilder();

foreach (DataRow dr in dt_Orders.Rows)
{
sb.AppendFormat("['{0}','{1}','{2}','{3}','
£{4}
','{5}'],", dr["Id"], dr["CustomerName"], dr["OrderItem"], dr["OrderStatus"], dr["OrderTotal"], dr["PNumber"]);
}


string Final;
Final = "[" + sb.ToString().TrimEnd(',') + "]";

string ScriptToRegister = @" Ext.onReady(function(){

Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

var myData"+this.ClientID+ @" = "+Final+@"

// create the data store
var store"+this.ClientID+ @" = new Ext.data.SimpleStore({
fields: [{name: 'Id'},
{name: 'CustomerName'},
{name: 'OrderItem'},
{name: 'OrderStatus'},
{name: 'Total'},
{name: 'PNumber'}]
});
store" + this.ClientID + @".loadData(myData" + this.ClientID + @");

// create the Grid
var grid" + this.ClientID + @" = new Ext.grid.GridPanel({
store: store" + this.ClientID + @",
columns: [
{header: 'Order No.', width: 70, sortable: false, dataIndex: 'Id'},
{header: 'Customer', sortable: true, dataIndex: 'CustomerName', width:150},
{header: 'Items', sortable: true, dataIndex: 'OrderItem', width: 60},
{header: 'Total', sortable: true, dataIndex: 'Total',width:70},
{id:'OrderStatus',header: 'Status', sortable: true, dataIndex: 'OrderStatus',width:125}
" + (OrderType==3?",{id:'PNumber',header: 'P Number', sortable: true, dataIndex: 'PNumber',width:100}":"")+@"
],
stripeRows: true,

height:255,
width:440
});

grid" + this.ClientID + @".render('" + div_Details.ClientID + @"');

grid" + this.ClientID + @".getSelectionModel().selectFirstRow();
});";//autoExpandColumn: 'OrderStatus',
Page.ClientScript.RegisterClientScriptBlock(typeof(string), "JsBlock"+this.ClientID, ScriptToRegister, true);
}
#endregion
}

Tuesday, July 29, 2008

Extending Linq class

Extending Linq.
Filed under: Extension Methods, IQueryable, Linq — Tags: DataSet, DataTable, Extension Methods, Linq — peteohanlon @ 12:47 pm

Sorry for the delay in continuing with the discussions on regular expressions, but I got a little sidetracked with the upgrade to Visual Studio 2008 (.NET 3.5), and all the “goodies” that it brings to you. For the moment I’m going to be putting the discussion on regular expressions to one side. I will get back to them but, for the moment, I want to take you on a journey into .NET 3.5.

Possibly the biggest headline in .NET 3.5 is the introduction of Linq. I have to admit that I was highly skeptical about how useful it will actually be in the “real world”, but having played around with it for a little while I have to admit that I’m actually quite impressed. It’s a well thought out area that actually does do a lot to increase productivity. Now, in this entry I’m not going to delve into the internals of Linq and how to use it. Instead, I’m going to talk about a feature of .NET 3.5 and how it can be used to “extend” the behaviour of Linq. Specifically, we’re going to look at how to use Extension Methods to add the ability to return a DataSet and DataTable from Linq in the same way you’d return a generic list.

The following code shows what you actually need to do to extend the IQueryable object in Linq. For the moment, don’t worry about what IQueryable actually does - once you’ve used Linq for a little while it becomes apparent what this interface is for, and where it fits into the big Linq picture.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Reflection;
using System.Data.Common;
using System.Data;
using System.Data.SqlClient; namespace LinqTesting
{
///
/// This class contains miscellaneous extension methods for Linq to Sql.
///

public static class LinqDataExtensions
{
///
/// Add the ability to return a DataTable based on a particular query
/// to a queryable object.
///

/// The IQueryable object to extend.
/// The query to execute.
/// The name of the datatable to be added.
/// The populated DataTable.
public static DataTable ToDataTable(this IQueryable extenderItem,
DbCommand query,
string tableName)
{
if (query == null)
{ throw new ArgumentNullException("query");
}
SqlCommand cmd = (SqlCommand)query;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
DataTable dt = new DataTable(tableName);
try
{
cmd.Connection.Open();
adapter.Fill(dt);
}
finally
{
cmd.Connection.Close(); }
return dt;
}
///
/// Add the ability to return a DataSet based on a particular query
/// to a queryable object.
///

/// The IQueryable object to extend.
/// The query to execute.
/// The name of the DataTable to be added.
/// The populated dataset.
public static DataSet ToDataSet(this IQueryable extenderItem,
DbCommand query,
string tableName)
{
if (query == null)
{
throw new ArgumentNullException("query");
}
return ToDataSet(extenderItem, query, null, tableName);
} ///
/// Add the ability to return a dataset based on a particular query
/// to a queryable object.
///

/// The IQueryable object to extend.
/// A generic dictionary containing the
/// query to execute along with the name of the table to add it to.
/// The populated dataset.
public static DataSet ToDataSet(this IQueryable extenderItem,
Dictionary query)
{
if (query == null)
{
throw new ArgumentNullException("query");
}
if (query.Count == 0)
{
throw new ArgumentException("query");
}
return ToDataSet(extenderItem, query, null);
} ///
/// Add the ability to return a dataset based on a particular query /// to a queryable object.
///

/// The IQueryable object to extend.
/// A generic dictionary containing the
/// query to execute along with the name of the table to add it to.
/// An optional DataSet. This allows application
/// to add multiple tables to the dataset.
/// The populated dataset.
public static DataSet ToDataSet(this IQueryable extenderItem,
Dictionary DbCommand> query,
DataSet dataSet)
{
if (query == null)
{
throw new ArgumentNullException("query");
}
if (query.Count == 0)
{
throw new ArgumentException("query");
}
if (dataSet == null) dataSet = new DataSet();

foreach (KeyValuePair kvp in query)
{
dataSet = LinqDataExtensions.ToDataSet(extenderItem,
kvp.Value,
dataSet,
kvp.Key);
}
return dataSet;
} ///
/// Add the ability to return a dataset based on a particular
/// query to a queryable object.
///

/// The IQueryable object to extend.
/// The query to execute.
/// An optional DataSet. This allows
/// application to add multiple tables to the dataset.
/// The name of the DataTable to be added.
/// The populated dataset.
public static DataSet ToDataSet(this IQueryable extenderItem,
DbCommand query,
DataSet dataSet,
string tableName)
{
if (query == null)
{
throw new ArgumentNullException("query");
}
if (dataSet == null)
dataSet = new DataSet();
DataTable tbl = LinqDataExtensions.ToDataTable(extenderItem,
query,
tableName);
if (tbl != null)
{
if (dataSet.Tables.Contains(tableName))
dataSet.Tables.Remove(tableName);
dataSet.Tables.Add(tbl);
}
return dataSet;
}
}
}

A couple of points to note about the class. Extension methods have to be in static classes, and they have to be static methods. In order to note what class is being extended, you use the “this” keyword before the first parameter. The code itself is fairly self explanatory and doesn’t do anything clever. The clever bit actually occurs in the Linq side. Here’s an example:

public DataSet GetDataSet()
{
IQueryable q = GetAllQuery();
return q.ToDataSet(context.GetCommand(GetAllQuery()), null, "MyTable");
}

private IQueryable GetAllQuery()
{
IQueryable q = from p in context.MyTables
select p; return q;
}

Why Constructors?

Why Constructors?

Initialization of values of different variables is critical in any application development. C# does initialize simple data-types to default values as per the language specification in the .Net framework, but for classes that are user specific, it is obvious that you would be the only one who can decide what is an ideal default value. The means of achieving this is Constructors. There is also a perception that constructors can only be used beyond initialization, which is true to some extent. We will examine them in the following sections.

Features of a Constructor

A Method that does not have a return type. E.g.

public class in4DataGrid
{
//Constructor declaration. Note after the modifier "public" keyword, there is no
//mention of a datatype or void. Also the name is same as that of class.
public in4DataGrid()
{
// Some Code Here.
}
}


Can either be static or Instance based. E.g.

public class in4DataGrid
{
//Static Constructor. Modifiers are irrelevant here.
static in4DataGrid()
{
// Some Code Here.
}
//Instance based
public in4DataGrid()
{
// Some Code Here.
}
}


Take parameters and behave just like any other method, which means that any instructions can be encapsulated in a constructor. E.g.

public class in4DataGrid
{
private int intWidth;
private int intHeight;
//Parameters intWidth and intHeight of type int.
public in4DataGrid(int Width, int Height)
{
intWidth = Width;
intHeight = Height;
//Some Code Here.
}
}


Constructors can be declared "private or protected" even though declaring them public is a common scenario. When declared as private, one cannot create an instance of the class or derive the class.


Can be overloaded. Further, one overloaded constructor can call the other one to take advantage of encapsulation and take negate the risks of code duplication within overloaded constructors (See the following section examples).
The following section deals with the how best to leverage the features of Constructors in our classes.

How to Use?

Use application logic in constructors carefully. Try to minimize unnecessary database operations in constructors like loading a Dataset that is used only in specific sections or on demand from the calling class. This is a performance overhead.


Do not write redundant code in overloaded constructors. This will become a huge maintenance issue as your class hierarchy grows and you start implementing more overloaded constructors in your derived classes. The following example shows a common section where in validation of initialization logic happens. E.g.

public class in4DataGrid
{
private int intWidth;
private int intHeight;
//Overloaded constructor 1 with no parameters. But the constructor initializes //the values by calling the other constructor which holds common business //validations by using the keyword "this".
public in4DataGrid():this(200,300)
{
//Some Code Here.
}
//Overloaded constructor 2 with parameters intWidth and intHeight of type //int.
public in4DataGrid(int Width, int Height)
{
intWidth = Width;
intHeight = Height;
// Do some business validation here.
if(intWidth > intHeight)
{
//Some code here
}
}
}


Try to use static constructors and variables when you are dealing with Global variables. This is especially a good design practice since you can initialize the static variables easily within static constructors instead of using constant variables. Other advantage would be to encapsulate your instruction logic for these variables. E.g.

public class in4DataGrid
{
private int intWidth;
private int intHeight;
private static int intMinimumHeight;
//Overloaded static constructor 1 with no parameters. But the constructor initializes the values by calling the other constructor.
static in4DataGrid()
{
//Some Business logic Here.
//Initialize the value based on logic.
intMinimumHeight=100;
}
//Overloaded instance based constructor 2 with parameters intWidth and //intHeight of type int.
public in4DataGrid(int Width, int Height)
{
if(Width > intMinimumWidth)
{
intWidth = Width;
intHeight = Height;
}
else
{
//Some Code Here.
}
}
}


Overloaded static constructors are dangerous when used to call other constructors, so try not to call other static constructor from within.


Design your derived class constructors carefully. This is because when an instance of derived class is created there is more than one constructor that will be called, i.e. both the base class and the derived class in the hierarchy. The constructors of the derived class first will run constructors of base class. The issue arises when you have overloaded constructor definitions in the base and derived classes. Overlooking here would prove costly. Make sure you use the keyword "base()" to make calls to overloaded base classes. E.g.

public class in4DataGrid: System.Data.DataGrid
{
//Constructor declaration. Use of keyword "base()" makes sure that the call is made to the base class(here it is System.Data.DataGrid). One can call any overloaded constructor of the base class this way.
public in4DataGrid(): base()
{
// Some Code Here.
}
}
Also note that the constructor initializers "base" and "this" are the only keywords that can be used when making a call to the base constructor, also any one among these can be specified.

Conclusion

Proper design of constructors goes a long way in solving some core problems faced in your class design. C# supports enormous flexibility to accommodate the use of various types of constructors. One has to judge the need of the application and never overlook the importance of constructors.

Class Modifiers and their uses in C# .Net

Class Modifiers and their uses in C# .Net
Filed under: Computer Science — Tags: Basic Programming, C#.Net, OOP — sadi02 @ 6:56 am

Class/Interface (Base class)
Inheritance (Inherited class)

Implementation (Interface)

(Child)
(Instance)

Is initiated??

General
Abstract
Sealed
Static*

General
Yes
Yes
Yes
No
No
Yes

Abstract
Yes
Yes
Yes
No
No
No

Sealed
No
No
No
No
No
Yes

Static
No
No
No
No
No
No

Interface
Yes
Yes
Yes
No
Yes
No





















This table is for showing relationship between a base class and child class

In this table I want to show the accessibility among the various types of classes and interface. From this table you also can know what type of class can be initiated. This is one example that helps you to understand the table.

If you use Abstract class as base class and take a general class as child and want to inherit, this will possible …here you can see..

Base: Abstract (ASadi)

Child: Interface (Sadi)

Accessibility: Yes

abstract class Sadi : ASadi

{

#region ASadi Members

public int getint() {

throw new Exception(“The method or operation is not implemented.”); }

#endregion

}

If you execute this code, it executes properly

From the first column of the table we can say that general class inherites both general and abstract class and also implements an interface. Theses classes can not inherites sealed as well as static class. only General and Sealed classes can be initiated.

From the table and above disscussion we can conclude that,

Abstract Class

A class defined as abstract is used as a base class. Such a class is used for the purpose of inheritance only i.e. other classes are derived from this class. We cannot create an object of an abstract class.An abstract class may contain methods and properties. The classes derived from the abstract class inherit these methods and properties. The abstract class may also contain abstract methods and properties. Abstract method and properties do not have any functionality. The derived class defines their full functionality.

Here is an example of an abstract class:

abstract class MyAbstract { public abstract void AbMethod(); }

Sealed Class

Classes can be declared as sealed. This is accomplished by putting the sealed keyword before the keyword class in the class definition. For example:

public sealed class classSealed { // Class members here. public string ID; public double Price; } A sealed class cannot be used as a base class. For this reason, it cannot also be an abstract class. Sealed classes are primarily used to prevent derivation. Because they can never be used as a base class, some run-time optimizations can make calling sealed class members slightly faster. Sealing a class means one can not derive from it. Sealing a method means one can not override it. In C# structs are implicitly sealed; therefore, they cannot be inherited. If we try to inherit from a sealed class in another class we will get compile time error about Inconsistent accessibility (code is shown in following code listing). In C# a method can not be declared as sealed. However when we override a method in a derived class, we can declare the overridden method as sealed as shown below. By declaring it as sealed, we can avoid further overriding of this method.

Static Class


Static classes are classes that contain only static members. Following is an example of static class. public static MyClass { …..}

A class defined as abstract is used as a base class. Such a class is used for the purpose of inheritance only i.e. other classes are derived from this class. We cannot create an object of an abstract class.An abstract class may contain methods and properties. The classes derived from the abstract class inherit these methods and properties. The abstract class may also contain abstract methods and properties. Abstract method and properties do not have any functionality. The derived class defines their full functionality.

Here is an example of an abstract class:

abstract class MyAbstract { public abstract void AbMethod(); }

Difference between class and struct in C# .Net

Difference between class and struct in C# .Net
Filed under: Computer Science — Tags: Basic Programming, C#.Net, OOP — sadi02 @ 8:40 am
1. Classes are reference types and structs are value types.
Since classes are reference type, a class variable can be assigned null.But we cannot assign null to
a struct variable, since structs are value type.
2. When you instantiate a class, it will be allocated on the heap.When you instantiate a struct, it gets created on the stack.
3. You will always be dealing with reference to an object ( instance ) of a class. But you will not be dealing with references to an instance of a struct ( but dealing directly with them ).
4. When passing a class to a method, it is passed by reference. When passing a struct to a method, it’s passed by value instead of as a reference.
5. You cannot have instance Field initializers in structs.But classes can have
example:
class MyClass
{
int myVar =10; // no syntax error.
public void MyFun( )
{
// statements
}
}
struct MyStruct
{
int myVar = 10; // syntax error.
public void MyFun( )
{
// statements
}
}
6. Classes can have explicit parameterless constructors. But structs cannot have
7. Classes must be instantiated using the new operator. But structs can be
8. Classes support inheritance.But there is no inheritance for structs.
( structs don’t support inheritance polymorphism )
9. Since struct does not support inheritance, access modifier of a member of a struct cannot be protected or protected internal.11. A class is permitted to declare a destructor.But a struct is not
12. classes are used for complex and large set data. structs are simple to use.

captcha class for c# developer

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;



public class CaptchaImage
{
// Public properties (all read-only).
public string Text
{
get { return this.text; }
}
public Bitmap Image
{
get { return this.image; }
}
public int Width
{
get { return this.width; }
}
public int Height
{
get { return this.height; }
}

// Internal properties.
private string text;
private int width;
private int height;
private string familyName;
private Bitmap image;

// For generating random numbers.
private Random random = new Random();

// ====================================================================
// Initializes a new instance of the CaptchaImage class using the
// specified text, width and height.
// ====================================================================
public CaptchaImage(string s, int width, int height)
{
this.text = s;
this.SetDimensions(width, height);
this.GenerateImage();
}

// ====================================================================
// Initializes a new instance of the CaptchaImage class using the
// specified text, width, height and font family.
// ====================================================================
public CaptchaImage(string s, int width, int height, string familyName)
{
this.text = s;
this.SetDimensions(width, height);
this.SetFamilyName(familyName);
this.GenerateImage();
}

// ====================================================================
// This member overrides Object.Finalize.
// ====================================================================
~CaptchaImage()
{
Dispose(false);
}

// ====================================================================
// Releases all resources used by this object.
// ====================================================================
public void Dispose()
{
GC.SuppressFinalize(this);
this.Dispose(true);
}

// ====================================================================
// Custom Dispose method to clean up unmanaged resources.
// ====================================================================
protected virtual void Dispose(bool disposing)
{
if (disposing)
// Dispose of the bitmap.
this.image.Dispose();
}

// ====================================================================
// Sets the image width and height.
// ====================================================================
private void SetDimensions(int width, int height)
{
// Check the width and height.
if (width <= 0)
throw new ArgumentOutOfRangeException("width", width, "Argument out of range, must be greater than zero.");
if (height <= 0)
throw new ArgumentOutOfRangeException("height", height, "Argument out of range, must be greater than zero.");
this.width = width;
this.height = height;
}

// ====================================================================
// Sets the font used for the image text.
// ====================================================================
private void SetFamilyName(string familyName)
{
// If the named font is not installed, default to a system font.
try
{
Font font = new Font(this.familyName, 12F);
this.familyName = familyName;
font.Dispose();
}
catch (Exception ex)
{
this.familyName = System.Drawing.FontFamily.GenericSerif.Name;
}
}

// ====================================================================
// Creates the bitmap image.
// ====================================================================
private void GenerateImage()
{
// Create a new 32-bit bitmap image.
Bitmap bitmap = new Bitmap(this.width, this.height, PixelFormat.Format32bppArgb);

// Create a graphics object for drawing.
Graphics g = Graphics.FromImage(bitmap);
g.SmoothingMode = SmoothingMode.AntiAlias;
Rectangle rect = new Rectangle(0, 0, this.width, this.height);

// Fill in the background.
HatchBrush hatchBrush = new HatchBrush(HatchStyle.SmallConfetti, Color.LightGray, Color.White);
g.FillRectangle(hatchBrush, rect);

// Set up the text font.
SizeF size;
float fontSize = rect.Height + 1;
Font font;
// Adjust the font size until the text fits within the image.
do
{
fontSize--;
font = new Font(this.familyName, fontSize, FontStyle.Bold);
size = g.MeasureString(this.text, font);
} while (size.Width > rect.Width);

// Set up the text format.
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;

// Create a path using the text and warp it randomly.
GraphicsPath path = new GraphicsPath();
path.AddString(this.text, font.FontFamily, (int)font.Style, font.Size, rect, format);
float v = 4F;
PointF[] points =
{
new PointF(this.random.Next(rect.Width) / v, this.random.Next(rect.Height) / v),
new PointF(rect.Width - this.random.Next(rect.Width) / v, this.random.Next(rect.Height) / v),
new PointF(this.random.Next(rect.Width) / v, rect.Height - this.random.Next(rect.Height) / v),
new PointF(rect.Width - this.random.Next(rect.Width) / v, rect.Height - this.random.Next(rect.Height) / v)
};
Matrix matrix = new Matrix();
matrix.Translate(0F, 0F);
path.Warp(points, rect, matrix, WarpMode.Perspective, 0F);

// Draw the text.
hatchBrush = new HatchBrush(HatchStyle.LargeConfetti, Color.Red, Color.Red);
g.FillPath(hatchBrush, path);

// Add some random noise.
int m = Math.Max(rect.Width, rect.Height);
for (int i = 0; i < (int)(rect.Width * rect.Height / 30F); i++)
{
int x = this.random.Next(rect.Width);
int y = this.random.Next(rect.Height);
int w = this.random.Next(m / 50);
int h = this.random.Next(m / 50);
g.FillEllipse(hatchBrush, x, y, w, h);
}

// Clean up.
font.Dispose();
hatchBrush.Dispose();
g.Dispose();

// Set the image.
this.image = bitmap;
}
}

compress a ASPX pagesthrough this class

compress a ASPX pgaeg through this class
========================================


#region Using



using System;

using System.Web;

using System.IO.Compression;



#endregion
///

/// Compresses the output using standard gzip/deflate.

///


namespace DAL
{
public class CompressionModule : IHttpModule
{
#region IHttpModule Members
void IHttpModule.Dispose()
{
// Nothing to dispose;
}
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
#endregion

#region Compression
private const string GZIP = "gzip";
private const string DEFLATE = "deflate";

void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app.Request.RawUrl.Contains(".aspx") || app.Request.RawUrl.Contains(".htm") )
{
if (IsEncodingAccepted(GZIP))
{
app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);
SetEncoding(GZIP);
}
else if (IsEncodingAccepted(DEFLATE))
{
app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);
SetEncoding(DEFLATE);
}
}
}

///
/// Checks the request headers to see if the specified
/// encoding is accepted by the client.
///

private bool IsEncodingAccepted(string encoding)
{
return HttpContext.Current.Request.Headers["Accept-encoding"] != null && HttpContext.Current.Request.Headers["Accept-encoding"].Contains(encoding);
}

///
/// Adds the specified encoding to the response headers.
///

///
private void SetEncoding(string encoding)
{
HttpContext.Current.Response.AppendHeader("Content-encoding", encoding);
}
#endregion
}
}

best perfomance in LINQ query

the performance can be drastically improved by turning off the change tracking service (context.ObjectTrackingEnabled=false) and by precompiling the queryies (CompiledQuery.Compile<>()).
Jim Wooley
http://blogs.msdn.com/alikl/archive/2007/12/18/asp-net-3-5-extensions-basic-steps-to-create-dynamic-data-web-application-focus-on-security-and-performance.aspx
http://www.codeplex.com/LINQ2SQLEB/SourceControl/ListDownloadableCommits.aspx
trouble shooting for LINQ
http://msdn2.microsoft.com/en-us/library/bb386996.aspx
\
http://blogs.msdn.com/mattwar/archive/2008/01/16/linq-building-an-iqueryable-provider-part-ix.aspx

http://blogs.msdn.com/adonet/archive/2008/03/27/ado-net-entity-framework-performance-comparison.aspx

To better understand how the query process affects performance, here’s the basic logic of a query, in order of execution.
• Parts of the query are broken up to allow for query caching to occur resulting in a query plan.
• Query is passed through to the .NET Framework data provider and executed against the database.
• The results are returned and the user iterates over the results.
• On each entity, the key properties are used to create an EntityKey.
• If the query is a tracking query then the EntityKey is used to do identity resolution.
• If the EntityKey is not found, the object is created and the properties copied into the object.
• The object is added to the ObjectStateManager for tracking.
• If merge options are used, then the properties follow the merge option rules.
• If the object is related to other objects in the ObjectContext, then the relationships between the entities are connected.

In my next post, I’ll show some of the performance improvements that can be made on the query itself and how Entity SQL and LINQ to Entities perform.
When optimizing query performance in the Entity Framework, you should consider what works best for your particular programming scenario. Here are a few key takeaways:
• Initial creation of the ObjectContext includes the cost of loading and validating the metadata.
• Initial execution of any query includes the costs of building up a query cache to enable faster execution of subsequent queries.
• Compiled LINQ queries are faster than Non-compiled LINQ queries.
• Queries executed with a NoTracking merge option work well for streaming large data objects or when changes and relationships do not need to be tracked.

Linq to SQL Deferred Loading - Lazy Load
Consider the Blog Site database I used in previous posts about Linq to SQL:

Linq to SQL Deferred Loading
If we query for the available blogs in the site using Linq to SQL, the query should look like this:
BlogDataContext ctx = new BlogDataContext(...);

var query = from b in ctx.Blogs
select b;

foreach (Blog b in query)
{
Console.WriteLine("{0}", b.BlogName);
}
This Linq query will result in the following SQL statement being sent to the DB:
SELECT [t0].[BlogID], [t0].[BlogName], [t0].[Owner]
FROM [dbo].[Blogs] AS [t0]
and the output will be:

Now, if we change the statement that outputs the name of the blog, and let it also print the number of posts in the blog:
foreach (Blog b in query)
{
Console.WriteLine("{0} has {1} posts", b.BlogName, b.Posts.Count);
}
This time, the output will be:

What Linq to SQL does is whenever it runs into the expression b.Posts.Count, it knows that the Posts collection of the blog was not yet retrieved, so it automatically generates the appropriate select statement and gets the posts. For example:
SELECT [t0].[PostID], [t0].[BlogID], [t0].[Title], [t0].[Body], [t0].[PublishDate]
FROM [dbo].[Posts] AS [t0]
WHERE [t0].[BlogID] = 'bursteg'
The problem is that a similar query is executed for each blog instance. So if we have a long list of blogs, than this simple loop can be a performance hit.
This behavior is called Linq to SQL Deferred Loading, and it is turned on by default. In order to turn it of, you can set the DeferredLoadingEnabled property to false.
BlogDataContext ctx = new BlogDataContext(...);

ctx.DeferredLoadingEnabled = false;

var query = from b in ctx.Blogs
select b;

foreach (Blog b in query)
{
Console.WriteLine("{0} has {1} posts", b.BlogName, b.Posts.Count);
}
Now, this query returns 0 as the number of posts of each blog.

Asynchronous Pages in ASP.NET 2.0

Asynchronous Pages in ASP.NET 2.0
============================
ASP.NET 2.0 is replete with new features ranging from declarative data binding and Master Pages to membership and role management services. But my vote for the coolest new feature goes to asynchronous pages, and here's why.
When ASP.NET receives a request for a page, it grabs a thread from a thread pool and assigns that request to the thread. A normal, or synchronous, page holds onto the thread for the duration of the request, preventing the thread from being used to process other requests. If a synchronous request becomes I/O bound—for example, if it calls out to a remote Web service or queries a remote database and waits for the call to come back—then the thread assigned to the request is stuck doing nothing until the call returns. That impedes scalability because the thread pool has a finite number of threads available. If all request-processing threads are blocked waiting for I/O operations to complete, additional requests get queued up waiting for threads to be free. At best, throughput decreases because requests wait longer to be processed. At worst, the queue fills up and ASP.NET fails subsequent requests with 503 "Server Unavailable" errors.
Asynchronous pages offer a neat solution to the problems caused by I/O-bound requests. Page processing begins on a thread-pool thread, but that thread is returned to the thread pool once an asynchronous I/O operation begins in response to a signal from ASP.NET. When the operation completes, ASP.NET grabs another thread from the thread pool and finishes processing the request. Scalability increases because thread-pool threads are used more efficiently. Threads that would otherwise be stuck waiting for I/O to complete can now be used to service other requests. The direct beneficiaries are requests that don't perform lengthy I/O operations and can therefore get in and out of the pipeline quickly. Long waits to get into the pipeline have a disproportionately negative impact on the performance of such requests.
The ASP.NET 2.0 Beta 2 async page infrastructure suffers from scant documentation. Let's fix that by surveying the landscape of async pages. Keep in mind that this column was developed with beta releases of ASP.NET 2.0 and the .NET Framework 2.0.


Asynchronous Pages in ASP.NET 1.x
ASP.NET 1.x doesn't support asynchronous pages per se, but it's possible to build them with a pinch of tenacity and a dash of ingenuity. For an excellent overview, see Fritz Onion's article entitled "Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code" in the June 2003 issue of MSDN®Magazine.
The trick here is to implement IHttpAsyncHandler in a page's codebehind class, prompting ASP.NET to process requests not by calling the page's IHttpHandler.ProcessRequest method, but by calling IHttpAsyncHandler.BeginProcessRequest instead. Your BeginProcessRequest implementation can then launch another thread. That thread calls base.ProcessRequest, causing the page to undergo its normal request-processing lifecycle (complete with events such as Load and Render) but on a non-threadpool thread. Meanwhile, BeginProcessRequest returns immediately after launching the new thread, allowing the thread that's executing BeginProcessRequest to return to the thread pool.
That's the basic idea, but the devil's in the details. Among other things, you need to implement IAsyncResult and return it from BeginProcessRequest. That typically means creating a ManualResetEvent object and signaling it when ProcessRequest returns in the background thread. In addition, you have to provide the thread that calls base.ProcessRequest. Unfortunately, most of the conventional techniques for moving work to background threads, including Thread.Start, ThreadPool.QueueUserWorkItem, and asynchronous delegates, are counterproductive in ASP.NET applications because they either steal threads from the thread pool or risk unconstrained thread growth. A proper asynchronous page implementation uses a custom thread pool, and custom thread pool classes are not trivial to write (for more information, see the .NET Matters column in the February 2005 issue of MSDN Magazine).
The bottom line is that building async pages in ASP.NET 1.x isn't impossible, but it is tedious. And after doing it once or twice, you can't help but think that there has to be a better way. Today there is—ASP.NET 2.0.


Asynchronous Pages in ASP.NET 2.0
ASP.NET 2.0 vastly simplifies the way you build asynchronous pages. You begin by including an Async="true" attribute in the page's @ Page directive, like so:
Copy Code
<%@ Page Async="true" ... %>
Under the hood, this tells ASP.NET to implement IHttpAsyncHandler in the page. Next, you call the new Page.AddOnPreRenderCompleteAsync method early in the page's lifetime (for example, in Page_Load) to register a Begin method and an End method, as shown in the following code:
Copy Code
AddOnPreRenderCompleteAsync (
new BeginEventHandler(MyBeginMethod),
new EndEventHandler (MyEndMethod)
);
What happens next is the interesting part. The page undergoes its normal processing lifecycle until shortly after the PreRender event fires. Then ASP.NET calls the Begin method that you registered using AddOnPreRenderCompleteAsync. The job of the Begin method is to launch an asynchronous operation such as a database query or Web service call and return immediately. At that point, the thread assigned to the request goes back to the thread pool. Furthermore, the Begin method returns an IAsyncResult that lets ASP.NET determine when the asynchronous operation has completed, at which point ASP.NET extracts a thread from the thread pool and calls your End method. After End returns, ASP.NET executes the remaining portion of the page's lifecycle, which includes the rendering phase. Between the time Begin returns and End gets called, the request-processing thread is free to service other requests, and until End is called, rendering is delayed. And because version 2.0 of the .NET Framework offers a variety of ways to perform asynchronous operations, you frequently don't even have to implement IAsyncResult. Instead, the Framework implements it for you.
The codebehind class in Figure 1 provides an example. The corresponding page contains a Label control whose ID is "Output". The page uses the System.Net.HttpWebRequest class to fetch the contents of http://msdn.microsoft.com. Then it parses the returned HTML and writes out to the Label control a list of all the HREF targets it finds.
Figure 1 AsyncPage.aspx.cs
Copy Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

public partial class AsyncPage : System.Web.UI.Page
{
private WebRequest _request;

void Page_Load (object sender, EventArgs e)
{
AddOnPreRenderCompleteAsync (
new BeginEventHandler(BeginAsyncOperation),
new EndEventHandler (EndAsyncOperation)
);
}

IAsyncResult BeginAsyncOperation (object sender, EventArgs e,
AsyncCallback cb, object state)
{
_request = WebRequest.Create("http://msdn.microsoft.com");
return _request.BeginGetResponse (cb, state);
}
void EndAsyncOperation (IAsyncResult ar)
{
string text;
using (WebResponse response = _request.EndGetResponse(ar))
{
using (StreamReader reader =
new StreamReader(response.GetResponseStream()))
{
text = reader.ReadToEnd();
}
}

Regex regex = new Regex ("href\\s*=\\s*\"([^\"]*)\"",
RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(text);

StringBuilder builder = new StringBuilder(1024);
foreach (Match match in matches)
{
builder.Append (match.Groups[1]);
builder.Append("
");
}

Output.Text = builder.ToString ();
}
}

Since an HTTP request can take a long time to return, AsyncPage.aspx.cs performs its processing asynchronously. It registers Begin and End methods in Page_Load, and in the Begin method, it calls HttpWebRequest.BeginGetResponse to launch an asynchronous HTTP request. BeginAsyncOperation returns to ASP.NET the IAsyncResult returned by BeginGetResponse, resulting in ASP.NET calling EndAsyncOperation when the HTTP request completes. EndAsyncOperation, in turn, parses the content and writes the results to the Label control, after which rendering occurs and an HTTP response goes back to the browser.

Figure 2 Synchronous vs. Asynchronous Page Processing
Figure 2 illustrates the difference between a synchronous page and an asynchronous page in ASP.NET 2.0. When a synchronous page is requested, ASP.NET assigns the request a thread from the thread pool and executes the page on that thread. If the request pauses to perform an I/O operation, the thread is tied up until the operation completes and the page lifecycle can be completed. An asychronous page, by contrast, executes as normal through the PreRender event. Then the Begin method that's registered using AddOnPreRenderCompleteAsync is called, after which the request-processing thread goes back to the thread pool. Begin launches an asynchronous I/O operation, and when the operation completes, ASP.NET grabs another thread from the thread pool and calls the End method and executes the remainder of the page's lifecycle on that thread.

Figure 3 Trace Output Shows Async Page's Async Point
The call to Begin marks the page's "async point." The trace in Figure 3 shows exactly where the async point occurs. If called, AddOnPreRenderCompleteAsync must be called before the async point—that is, no later than the page's PreRender event.


Asynchronous Data Binding
It's not all that common for ASP.NET pages to use HttpWebRequest directly to request other pages, but it is common for them to query databases and data bind the results. So how would you use asynchronous pages to perform asynchronous data binding? The codebehind class in Figure 4 shows one way to go about it.
Figure 4 AsyncDataBind.aspx.cs
Copy Code
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;

public partial class AsyncDataBind : System.Web.UI.Page
{
private SqlConnection _connection;
private SqlCommand _command;
private SqlDataReader _reader;


protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Hook PreRenderComplete event for data binding
this.PreRenderComplete +=
new EventHandler(Page_PreRenderComplete);

// Register async methods
AddOnPreRenderCompleteAsync(
new BeginEventHandler(BeginAsyncOperation),
new EndEventHandler(EndAsyncOperation)
);
}
}
IAsyncResult BeginAsyncOperation (object sender, EventArgs e,
AsyncCallback cb, object state)
{
string connect = WebConfigurationManager.ConnectionStrings
["PubsConnectionString"].ConnectionString;
_connection = new SqlConnection(connect);
_connection.Open();
_command = new SqlCommand(
"SELECT title_id, title, price FROM titles", _connection);
return _command.BeginExecuteReader (cb, state);
}

void EndAsyncOperation(IAsyncResult ar)
{
_reader = _command.EndExecuteReader(ar);
}

protected void Page_PreRenderComplete(object sender, EventArgs e)
{
Output.DataSource = _reader;
Output.DataBind();
}

public override void Dispose()
{
if (_connection != null) _connection.Close();
base.Dispose();
}
}

AsyncDataBind.aspx.cs uses the same AddOnPreRenderCompleteAsync pattern that AsyncPage.aspx.cs uses. But rather than call HttpWebRequest.BeginGetResponse, its BeginAsyncOperation method calls SqlCommand.BeginExecuteReader (new in ADO.NET 2.0), to perform an asynchronous database query. When the call completes, EndAsyncOperation calls SqlCommand.EndExecuteReader to get a SqlDataReader, which it then stores in a private field. In an event handler for the PreRenderComplete event, which fires after the asynchronous operation completes but before the page is rendered, it then binds the SqlDataReader to the Output GridView control. On the outside, the page looks like a normal (synchronous) page that uses a GridView to render the results of a database query. But on the inside, this page is much more scalable because it doesn't tie up a thread-pool thread waiting for the query to return.


Calling Web Services Asynchronously
Another I/O-related task commonly performed by ASP.NET Web pages is callouts to Web services. Since Web service calls can take a long time to return, pages that execute them are ideal candidates for asynchronous processing.
Figure 5 shows one way to build an asynchronous page that calls out to a Web service. It uses the same AddOnPreRenderCompleteAsync mechanism featured in Figure 1 and Figure 4. The page's Begin method launches an asynchronous Web service call by calling the Web service proxy's asynchronous Begin method. The page's End method caches in a private field a reference to the DataSet returned by the Web method, and the PreRenderComplete handler binds the DataSet to a GridView. For reference, the Web method targeted by the call is shown in the following code:
Copy Code
[WebMethod]
public DataSet GetTitles ()
{
string connect = WebConfigurationManager.ConnectionStrings
["PubsConnectionString"].ConnectionString;
SqlDataAdapter adapter = new SqlDataAdapter
("SELECT title_id, title, price FROM titles", connect);
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds;
}
Figure 5 AsyncWSInvoke1.aspx.cs
Copy Code
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class AsyncWSInvoke1 : System.Web.UI.Page
{
private WS.PubsWebService _ws;
private DataSet _ds;

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Hook PreRenderComplete event for data binding
this.PreRenderComplete +=
new EventHandler(Page_PreRenderComplete);

// Register async methods
AddOnPreRenderCompleteAsync(
new BeginEventHandler(BeginAsyncOperation),
new EndEventHandler(EndAsyncOperation)
);
}
}

IAsyncResult BeginAsyncOperation (object sender, EventArgs e,
AsyncCallback cb, object state)
{
_ws = new WS.PubsWebService();
// Fix up URL for call to local VWD-hosted Web service
_ws.Url = new Uri(Request.Url, "Pubs.asmx").ToString();
_ws.UseDefaultCredentials = true;
return _ws.BeginGetTitles (cb, state);
}

void EndAsyncOperation(IAsyncResult ar)
{
_ds = _ws.EndGetTitles(ar);
}

protected void Page_PreRenderComplete(object sender, EventArgs e)
{
Output.DataSource = _ds;
Output.DataBind();
}

public override void Dispose()
{
if (_ws != null) _ws.Dispose();
base.Dispose();
}
}

That's one way to do it, but it's not the only way. The .NET Framework 2.0 Web service proxies support two mechanisms for placing asynchronous calls to Web services. One is the per-method Begin and End methods featured in .NET Framework 1.x. and 2.0 Web service proxies. The other is the new MethodAsync methods and MethodCompleted events found only in the Web service proxies of the .NET Framework 2.0.
If a Web service has a method named Foo, then in addition to having methods named Foo, BeginFoo, and EndFoo, a .NET Framework version 2.0 Web service proxy includes a method named FooAsync and an event named FooCompleted. You can call Foo asynchronously by registering a handler for FooCompleted events and calling FooAsync, like this:
Copy Code
proxy.FooCompleted += new FooCompletedEventHandler (OnFooCompleted);
proxy.FooAsync (...);
...
void OnFooCompleted (Object source, FooCompletedEventArgs e)
{
// Called when Foo completes
}
When the asynchronous call begun by FooAsync completes, a FooCompleted event fires, causing your FooCompleted event handler to be called. Both the delegate wrapping the event handler (FooCompletedEventHandler) and the second parameter passed to it (FooCompletedEventArgs) are generated along with the Web service proxy. You can access Foo's return value through FooCompletedEventArgs.Result.
Figure 6 presents a codebehind class that calls a Web service's GetTitles method asynchronously using the MethodAsync pattern. Functionally, this page is identical to the one in Figure 5. Internally, it's quite different. AsyncWSInvoke2.aspx includes an @ Page Async="true" directive, just like AsyncWSInvoke1.aspx. But AsyncWSInvoke2.aspx.cs doesn't call AddOnPreRenderCompleteAsync; it registers a handler for GetTitlesCompleted events and calls GetTitlesAsync on the Web service proxy. ASP.NET still delays rendering the page until GetTitlesAsync completes. Under the hood, it uses an instance of System.Threading.SynchronizationContext, another new class in 2.0, to receive notifications when the asynchronous call begins and when it completes.
Figure 6 AsyncWSInvoke2.aspx.cs
Copy Code
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class AsyncWSInvoke2 : System.Web.UI.Page
{
private WS.PubsWebService _ws;
private DataSet _ds;

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Hook PreRenderComplete event for data binding
this.PreRenderComplete +=
new EventHandler(Page_PreRenderComplete);

// Call the Web service asynchronously
_ws = new WS.PubsWebService();
_ws.GetTitlesCompleted += new
WS.GetTitlesCompletedEventHandler(GetTitlesCompleted);
_ws.Url = new Uri(Request.Url, "Pubs.asmx").ToString();
_ws.UseDefaultCredentials = true;
_ws.GetTitlesAsync();
}
}

void GetTitlesCompleted(Object source,
WS.GetTitlesCompletedEventArgs e)
{
_ds = e.Result;
}

protected void Page_PreRenderComplete(object sender, EventArgs e)
{
Output.DataSource = _ds;
Output.DataBind();
}

public override void Dispose()
{
if (_ws != null) _ws.Dispose();
base.Dispose();
}
}

There are two advantages to using MethodAsync rather than AddOnPreRenderCompleteAsync to implement asynchronous pages. First, MethodAsync flows impersonation, culture, and HttpContext.Current to the MethodCompleted event handler. AddOnPreRenderCompleteAsync does not. Second, if the page makes multiple asynchronous calls and must delay rendering until all the calls have been completed, using AddOnPreRenderCompleteAsync requires you to compose an IAsyncResult that remains unsignaled until all the calls have completed. With MethodAsync, no such hijinks are necessary; you simply place the calls, as many of them as you like, and the ASP.NET engine delays the rendering phase until the final call returns.


Asynchronous Tasks
MethodAsync is a convenient way to make multiple asynchronous Web service calls from an asynchronous page and delay the rendering phase until all the calls complete. But what if you want to perform several asynchronous I/O operations in an asynchronous page and those operations don't involve Web services? Does that mean you're back to composing an IAsyncResult that you can return to ASP.NET to let it know when the last call has completed? Fortunately, no.
In ASP.NET 2.0, the System.Web.UI.Page class introduces another method to facilitate asynchronous operations: RegisterAsyncTask. RegisterAsyncTask has four advantages over AddOnPreRenderCompleteAsync. First, in addition to Begin and End methods, RegisterAsyncTask lets you register a timeout method that's called if an asynchronous operation takes too long to complete. You can set the timeout declaratively by including an AsyncTimeout attribute in the page's @ Page directive. AsyncTimeout="5" sets the timeout to 5 seconds. The second advantage is that you can call RegisterAsyncTask several times in one request to register several async operations. As with MethodAsync, ASP.NET delays rendering the page until all the operations have completed. Third, you can use RegisterAsyncTask's fourth parameter to pass state to your Begin methods. Finally, RegisterAsyncTask flows impersonation, culture, and HttpContext.Current to the End and Timeout methods. As mentioned earlier in this discussion, the same is not true of an End method registered with AddOnPreRenderCompleteAsync.
In other respects, an asynchronous page that relies on RegisterAsyncTask is similar to one that relies on AddOnPreRenderCompleteAsync. It still requires an Async="true" attribute in the @ Page directive (or the programmatic equivalent, which is to set the page's AsyncMode property to true), and it still executes as normal through the PreRender event, at which time the Begin methods registered using RegisterAsyncTask are called and further request processing is put on hold until the last operation completes.To demonstrate, the codebehind class in Figure 7 is functionally equivalent to the one in Figure 1, but it uses RegisterTaskAsync instead of AddOnPreRenderCompleteAsync. Note the timeout handler named TimeoutAsyncOperation, which is called if HttpWebRequest.BeginGetRequest takes too long to complete. The corresponding .aspx file includes an AsyncTimeout attribute that sets the timeout interval to 5 seconds. Also note the null passed in RegisterAsyncTask's fourth parameter, which could have been used to pass data to the Begin method.
Figure 7 AsyncPageTask.aspx.cs
Copy Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

public partial class AsyncPageTask : System.Web.UI.Page
{
private WebRequest _request;

protected void Page_Load(object sender, EventArgs e)
{
PageAsyncTask task = new PageAsyncTask(
new BeginEventHandler(BeginAsyncOperation),
new EndEventHandler(EndAsyncOperation),
new EndEventHandler(TimeoutAsyncOperation),
null
);
RegisterAsyncTask(task);
}

IAsyncResult BeginAsyncOperation(object sender, EventArgs e,
AsyncCallback cb, object state)
{
_request = WebRequest.Create("http://msdn.microsoft.com");
return _request.BeginGetResponse(cb, state);
}

void EndAsyncOperation(IAsyncResult ar)
{
string text;
using (WebResponse response = _request.EndGetResponse(ar))
{
using (StreamReader reader =
new StreamReader(response.GetResponseStream()))
{
text = reader.ReadToEnd();
}
}

Regex regex = new Regex("href\\s*=\\s*\"([^\"]*)\"",
RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(text);

StringBuilder builder = new StringBuilder(1024);
foreach (Match match in matches)
{
builder.Append(match.Groups[1]);
builder.Append("
");
}

Output.Text = builder.ToString();
}

void TimeoutAsyncOperation(IAsyncResult ar)
{
Output.Text = "Data temporarily unavailable";
}
}

The primary advantage of RegisterAsyncTask is that it allows asynchronous pages to fire off multiple asynchronous calls and delay rendering until all the calls have completed. It works perfectly well for one asynchronous call, too, and it offers a timeout option that AddOnPreRenderCompleteAsync doesn't. If you build an asynchronous page that makes just one async call, you can use AddOnPreRenderCompleteAsync or RegisterAsyncTask. But for asynchronous pages that place two or more async calls, RegisterAsyncTask simplifies your life considerably.
Since the timeout value is a per-page rather than per-call setting, you may be wondering whether it's possible to vary the timeout value for individual calls. The short answer is no. You can vary the timeout from one request to the next by programmatically modifying the page's AsyncTimeout property, but you can't assign different timeouts to different calls initiated from the same request.


Wrapping It Up
So there you have it—the skinny on asynchronous pages in ASP.NET 2.0. They're significantly easier to implement in this upcoming version of ASP.NET, and the architecture is such that you can batch multiple async I/O operations in one request and delay the rendering of the page until all the operations have completed. Combined with async ADO.NET and other new asynchronous features in the .NET Framework, async ASP.NET pages offer a powerful and convenient solution to the problem of I/O-bound requests that inhibit scalability by saturating the thread pool.
A final point to keep in mind as you build asynchronous pages is that you should not launch asynchronous operations that borrow from the same thread pool that ASP.NET uses. For example, calling ThreadPool.QueueUserWorkItem at a page's asynchronous point is counterproductive because that method draws from the thread pool, resulting in a net gain of zero threads for processing requests. By contrast, calling asynchronous methods built into the Framework, methods such as HttpWebRequest.BeginGetResponse and SqlCommand.BeginExecuteReader, is generally considered to be safe because those methods tend to use completion ports to implement asynchronous behavior.

The ASP.NET 2.0 Page Model

The ASP.NET 2.0 Page Model

In ASP.NET 1.x, developers had a choice between an inline code model and a code-behind code model. Code-behind could be implemented using either the Src attribute or the CodeBehind attribute of the @Page directive. In ASP.NET 2.0, developers still have a choice between inline code and code-behind, but there have been significant enhancements to the code-behind model.

« Previous Module | Next Module »

In ASP.NET 1.x, developers had a choice between an inline code model and a code-behind code model. Code-behind could be implemented using either the Src attribute or the CodeBehind attribute of the @Page directive. In ASP.NET 2.0, developers still have a choice between inline code and code-behind, but there have been significant enhancements to the code-behind model.

Improvements in the Code-Behind Model
In order to fully understand the changes in the code-behind model in ASP.NET 2.0, its best to quickly review the model as it existed in ASP.NET 1.x.

The Code-Behind Model in ASP.NET 1.x
In ASP.NET 1.x, the code-behind model consisted of an ASPX file (the Webform) and a code-behind file containing programming code. The two files were connected using the @Page directive in the ASPX file. Each control on the ASPX page had a corresponding declaration in the code-behind file as an instance variable. The code-behind file also contained code for event binding and generated code necessary for the Visual Studio designer. This model worked fairly well, but because every ASP.NET element in the ASPX page required corresponding code in the code-behind file, there was no true separation of code and content. For example, if a designer added a new server control to an ASPX file outside of the Visual Studio IDE, the application would break due to the absence of a declaration for that control in the code-behind file.

The Code-Behind Model in ASP.NET 2.0
ASP.NET 2.0 greatly improves upon this model. In ASP.NET 2.0, code-behind is implemented using the new partial classes provided in ASP.NET 2.0. The code-behind class in ASP.NET 2.0 is definied as a partial class meaning that it contains only part of the classs definition. The remaining part of the class definition is dynamically generated by ASP.NET 2.0 using the ASPX page at runtime or when the Web site is precompiled. The link between the code-behind file and the ASPX page is still established using the @ Page directive. However, instead of a CodeBehind or Src attribute, ASP.NET 2.0 now uses the CodeFile attribute. The Inherits attribute is also used to specify the class name for the page.

A typical @ Page directive might look like this:

<%@Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
A typical class definition in an ASP.NET 2.0 code-behind file might look like this:

public partial class _Default : System.Web.UI.Page
Note: C# and Visual Basic are the only managed languages that currently support partial classes. Therefore, developers using J# will not be able to use the code-behind model in ASP.NET 2.0.

The new model enhances the code-behind model because developers will now have code files that contain only the code that they have created. It also provides for a true separation of code and content because there are no instance variable declarations in the code-behind file.

Note: Because the partial class for the ASPX page is where event binding takes place, Visual Basic developers can realize a slight performance increase by using the Handles keyword in code-behind to bind events. C# has no equivalent keyword.

New @ Page Directive Attributes
ASP.NET 2.0 adds many new attributes to the @ Page directive. The following attributes are new in ASP.NET 2.0.

Async
The Async attribute allows you to configure page to be executed asynchronously. Well cover asynchronous pages later in this module.

AsyncTimeout
Specified the timeout for asynchronous pages. The default is 45 seconds.

CodeFile
The CodeFile attribute is the replacement for the CodeBehind attribute in Visual Studio 2002/2003.

CodeFileBaseClass
The CodeFileBaseClass attribute is used in cases where you want multiple pages to derive from a single base class. Because of the implementation of partial classes in ASP.NET, without this attribute, a base class that uses shared common fields to reference controls declared in an ASPX page would not work properly because ASP.NETs compilation engine will automatically create new members based on controls in the page. Therefore, if you want a common base class for two or more pages in ASP.NET, you will need to define specify your base class in the CodeFileBaseClass attribute and then derive each pages class from that base class. The CodeFile attribute is also required when this attribute is used.

CompilationMode
This attribute allows you to set the CompilationMode property of the ASPX page. The CompilationMode property is an enumeration containing the values Always, Auto, and Never. The default is Always. The Auto setting will prevent ASP.NET from dynamically compiling the page if possible. Excluding pages from dynamic compilation increases performance. However, if a page that is excluded contains that code that must be compiled, an error will be thrown when the page is browsed.

EnableEventValidation
This attribute specifies whether or not postback and callback events are validated. When this is enabled, arguments to postback or callback events are checked to ensure that they originated from the server control that originally rendered them.

EnableTheming
This attribute specifies whether or not ASP.NET themes are used on a page. The default is false. ASP.NET themes are covered in Module 10.

LinePragmas
This attribute specifies whether line pragmas should be added during compilation. Line pragmas are options used by debuggers to mark specific sections of code.

MaintainScrollPositionOnPostback
This attribute specifies whether or not JavaScript is injected into the page in order to maintain scroll position between postbacks. This attribute is false by default.

When this attribute is true, ASP.NET will add a
Note that the src for this script block is WebResource.axd. This resource is not a physical path. When this script is requested, ASP.NET dynamically builds the script.

MasterPageFile
This attribute specifies the master page file for the current page. The path can be relative or absolute. Master pages are covered in Module 4.

StyleSheetTheme
This attribute allows you to override user-interface appearance properties defined by an ASP.NET 2.0 theme. Themes are covered in Module 10.

Theme
Specifies the theme for the page. If a value is not specified for the StyleSheetTheme attribute, the Theme attribute overrides all styles applied to controls on the page.

Title
Sets the title for the page. The value specified here will appear in the element of the rendered page. <br /> <br />ViewStateEncryptionMode <br />Sets the value for the ViewStateEncryptionMode enumeration. The available values are Always, Auto, and Never. The default value is Auto. When this attribute is set to a value of Auto, viewstate is encrypted is a control requests it by calling the RegisterRequiresViewStateEncryption method. <br /> <br />Setting Public Property Values via the @ Page Directive <br />Another new capability of the @ Page directive in ASP.NET 2.0 is the ability to set the initial value of public properties of a base class. Suppose, for example, that you have a public property called SomeText in your base class and you’d like it to be initialized to Hello when a page is loaded. You can accomplish this by simply setting the value in the @ Page directive like so: <br /> <br /><%@Page Language="C#" SomeText="Hello!" Inherits="PageBase" %> <br />The SomeText attribute of the @ Page directive sets the initial value of the SomeText property in the base class to Hello!. The video below is a walkthrough of setting the initial value of a public property in a base class using the @ Page directive. <br /> <br /> <br />Open Full-Screen Video <br /> <br />New Public Properties of the Page Class <br />The following public properties are new in ASP.NET 2.0. <br /> <br />AppRelativeTemplateSourceDirectory <br />Returns the application-relative path to the page or control. For example, for a page located at http://app/folder/page.aspx, the property returns ~/folder/. <br /> <br />AppRelativeVirtualPath <br />Returns the relative virtual directory path to the page or control. For example for a page located at http://app/folder/page.aspx, the property returns ~/folder/page.aspx. <br /> <br />AsyncTimeout <br />Gets or sets the timeout used for asynchronous page handling. (Asynchronous pages will be covered later in this module.) <br /> <br />ClientQueryString <br />A read-only property that returns the query string portion of the requested URL. This value is URL encoded. You can use the UrlDecode method of the HttpServerUtility class to decode it. <br /> <br />ClientScript <br />This property returns a ClientScriptManager object that can be used to manage ASP.NETs emission of client-side script. (The ClientScriptManager class is covered later in this module.) <br /> <br />EnableEventValidation <br />This property controls whether or not event validation is enabled for postback and callback events. When enabled, arguments to postback or callback events are verified to ensure that they originated from the server control that originally rendered them. <br /> <br />EnableTheming <br />This property gets or sets a Boolean that specifies whether or not an ASP.NET 2.0 theme applies to the page. <br /> <br />Form <br />This property returns the HTML form on the ASPX page as an HtmlForm object. <br /> <br />Header <br />This property returns a reference to an HtmlHead object that contains the page header. You can use the returned HtmlHead object to get/set style sheets, Meta tags, etc. <br /> <br />IdSeparator <br />This read-only property gets the character that is used to separate control identifiers when ASP.NET is building a unique ID for controls on a page. It is not intended to be used directly from your code. <br /> <br />IsAsync <br />This property allows for asynchronous pages. Asynchronous pages are discussed later in this module. <br /> <br />IsCallback <br />This read-only property returns true if the page is the result of a call back. Call backs are discussed later in this module. <br /> <br />IsCrossPagePostBack <br />This read-only property returns true if the page is part of a cross-page postback. Cross-page postbacks are covered later in this module. <br /> <br />Items <br />Returns a reference to an IDictionary instance that contains all objects stored in the pages context. You can add items to this IDictionary object and they will be available to you throughout the lifetime of the context. <br /> <br />MaintainScrollPositionOnPostBack <br />This property controls whether or not ASP.NET emits JavaScript that maintains the pages scroll position in the browser after a postback occurs. (Details of this property were discussed earlier in this module.) <br /> <br />Master <br />This read-only property returns a reference to the MasterPage instance for a page to which a master page has been applied. <br /> <br />MasterPageFile <br />Gets or sets the master page filename for the page. This property can only be set in the PreInit method. <br /> <br />MaxPageStateFieldLength <br />This property gets or sets the maximum length for the pages state in bytes. If the property is set to a positive number, the pages view state will be broken up into multiple hidden fields so that it doesnt exceed the number of bytes specified. If the property is a negative number, the view state will not be broken into chunks. <br /> <br />PageAdapter <br />Returns a reference to the PageAdapter object that modifies the page for the requesting browser. <br /> <br />PreviousPage <br />Returns a reference to the previous page in cases of a Server.Transfer or a cross-page postback. <br /> <br />SkinID <br />Specifies the ASP.NET 2.0 skin to apply to the page. <br /> <br />StyleSheetTheme <br />This property gets or sets the style sheet that is applied to a page. <br /> <br />TemplateControl <br />Returns a reference to the containing control for the page. <br /> <br />Theme <br />Gets or sets the name of the ASP.NET 2.0 theme applied to the page. This value must be set prior to the PreInit method. <br /> <br />Title <br />This property gets or sets the title for the page as obtained from the pages header. <br /> <br />ViewStateEncryptionMode <br />Gets or sets the ViewStateEncryptionMode of the page. See a detailed discussion of this property earlier in this module. <br /> <br />New Protected Properties of the Page Class <br />The following are the new protected properties of the Page class in ASP.NET 2.0. <br /> <br />Adapter <br />Returns a reference to the ControlAdapter that renders the page on the device that requested it. <br /> <br />AsyncMode <br />This property indicates whether or not the page is processed asynchronously. It is intended for use by the runtime and not directly in code. <br /> <br />ClientIDSeparator <br />This property returns the character used as a separator when creating unique client IDs for controls. It is intended for use by the runtime and not directly in code. <br /> <br />PageStatePersister <br />This property returns the PageStatePersister object for the page. This property is primarily used by ASP.NET control developers. <br /> <br />UniqueFilePathSuffix <br />This property returns a unique suffic that is appended to the file path for caching browsers. The default value is __ufps= and a 6-digit number. <br /> <br />New Public Methods for the Page Class <br />The following public methods are new to the Page class in ASP.NET 2.0. <br /> <br />AddOnPreRenderCompleteAsync <br />This method registers event handler delegates for asynchronous page execution. Asynchronous pages are discussed later in this module. <br /> <br />ApplyStyleSheetSkin <br />Applies the properties in a pages style sheet to the page. <br /> <br />ExecuteRegisteredAsyncTasks <br />This method beings an asynchronous task. <br /> <br />GetValidators <br />Returns a collection of validators for the specified validation group or the default validation group if none is specified. <br /> <br />RegisterAsyncTask <br />This method registers a new async task. Asynchronous pages are covered later in this module. <br /> <br />RegisterRequiresControlState <br />This method tells ASP.NET that the pages control state must be persisted. <br /> <br />RegisterRequiresViewStateEncryption <br />This method tells ASP.NET that the pages viewstate requires encryption. <br /> <br />ResolveClientUrl <br />Returns a relative URL that can be used for client requests for images, etc. <br /> <br />SetFocus <br />This method will set the focus to the control that is specified when the page is initially loaded. <br /> <br />UnregisterRequiresControlState <br />This method will unregister the control that is passed to it as no longer requiring control state persistence. <br /> <br />Changes to the Page Lifecycle <br />The page lifecycle in ASP.NET 2.0 hasnt changed dramatically, but there are some new methods that you should be aware of. The ASP.NET 2.0 page lifecycle is outlined below. <br /> <br />PreInit (New in ASP.NET 2.0) <br />The PreInit event is the earliest stage in the lifecycle that a developer can access. The addition of this event makes it possible to programmatically change ASP.NET 2.0 themes, master pages, access properties for an ASP.NET 2.0 profile, etc. If you are in a postback state, its important to realize that Viewstate has not yet been applied to controls at this point in the lifecycle. Therefore, if a developer changes a property of a control at this stage, it will likely be overwritten later in the pages lifecycle. <br /> <br />Init <br />The Init event has not changed from ASP.NET 1.x. This is where you would want to read or initialize properties of controls on your page. At this stage, master pages, themes, etc. are already applied to the page. <br /> <br />InitComplete (New in 2.0) <br />The InitComplete event is called at the end of the pages initialization stage. At this point in the lifecycle, you can access controls on the page, but their state has not yet been populated. <br /> <br />PreLoad (New in 2.0) <br />This event is called after all postback data has been applied and just prior to Page_Load. <br /> <br />Load <br />The Load event has not changed from ASP.NET 1.x. <br /> <br />LoadComplete (New in 2.0) <br />The LoadComplete event is the last event in the pages load stage. At this stage, all postback and viewstate data has been applied to the page. <br /> <br />PreRender <br />If you would like for viewstate to be properly maintained for controls that are added to the page dynamically, the PreRender event is the last opportunity to add them. <br /> <br />PreRenderComplete (New in 2.0) <br />At the PreRenderComplete stage, all controls have been added to the page and the page is ready to be rendered. The PreRenderComplete event is the last event raised before the pages viewstate is saved. <br /> <br />SaveStateComplete (New in 2.0) <br />The SaveStateComplete event is called immediately after all page viewstate and control state has been saved. This is the last event before the page is actually rendered to the browser. <br /> <br />Render <br />The Render method has not changed since ASP.NET 1.x. This is where the HtmlTextWriter is initialized and the page is rendered to the browser. <br /> <br />Cross-Page Postback in ASP.NET 2.0 <br />In ASP.NET 1.x, postbacks were required to post to the same page. Cross-page postbacks were not allowed. ASP.NET 2.0 adds the ability to post back to a different page via the IButtonControl interface. Any control that implements the new IButtonControl interface (Button, LinkButton, and ImageButton in addition to third-party custom controls) can take advantage of this new functionality via the use of the PostBackUrl attribute. The following code shows a Button control that posts back to a second page. <br /> <br /><asp:Button ID="SubmitReport" PostBackUrl="~/Default.aspx" <br /> runat="server" Text="Submit Report" /> <br />When the page is posted back, the Page that initiates the postback is accessible via the PreviousPage property on the second page. This functionality is implemented via the new WebForm_DoPostBackWithOptions client-side function that ASP.NET 2.0 renders to the page when a control posts back to a different page. This JavaScript function is provided by the new WebResource.axd handler which emits script to the client. <br /> <br />The video below is a walkthrough of a cross-page postback. <br /> <br /> <br />Open Full-Screen Video <br /> <br />More Details on Cross-Page Postbacks <br />Viewstate <br />You may have asked yourself already about what happens to the viewstate from the first page in a cross-page postback scenario. After all, any control that does not implement IPostBackDataHandler will persist its state via viewstate, so to have access to the properties of that control on the second page of a cross-page postback, you must have access to the viewstate for the page. ASP.NET 2.0 takes care of this scenario using a new hidden field in the second page called __PREVIOUSPAGE. The __PREVIOUSPAGE form field contains the viewstate for the first page so that you can have access to the properties of all controls in the second page. <br /> <br />Circumventing FindControl <br />In the video walkthrough of a cross-page postback, I used the FindControl method to get a reference to the TextBox control on the first page. That method works well for that purpose, but FindControl is expensive and it requires writing additional code. Fortunately, ASP.NET 2.0 provides an alternative to FindControl for this purpose that will work in many scenarios. The PreviousPageType directive allows you to have a strongly-typed reference to the previous page by using either the TypeName or the VirtualPath attribute. The TypeName attribute allows you to specify the type of the previous page while the VirtualPath attribute allows you to refer to the previous page using a virtual path. After youve set the PreviousPageType directive, you must then expose the controls, etc. to which you want to allow access using public properties. <br /> <br />Lab1 Cross-Page Postback <br />In this lab, you will create an application that uses the new cross-page postback functionality of ASP.NET 2.0. <br /> <br />Open Visual Studio 2005 and create a new ASP.NET Web site. <br />Add a new Webform called page2.aspx. <br />Open the Default.aspx in Design view and add a Button control and a TextBox control. <br />Give the Button control an ID of SubmitButton and the TextBox control an ID of UserName. <br />Set the PostBackUrl property of the Button to page2.aspx. <br />Open page2.aspx in Source view. <br />Add a @ PreviousPageType directive as shown below: <br />Add the following code to the Page_Load of page2.aspx's code-behind: <br />Response.Write(PreviousPage.UserName.Text);Build the project by clicking on Build on the Build menu. <br />Add the following code to the code-behind for Default.aspx: <br />public TextBox txtUserName { <br /> get { return this.UserName; } <br />}Change the Page_Load in page2.aspx to the following: <br />Response.Write(PreviousPage.txtUserName.Text);Build the project. <br />Run the project. <br />Enter your name in the TextBox and click the button. <br />What is the result? <br />Asynchronous Pages in ASP.NET 2.0 <br />Many contention problems in ASP.NET are caused by latency of external calls (such as Web service or database calls), file IO latency, etc. When a request is made against an ASP.NET application, ASP.NET uses one of its worker threads to service that request. That request owns that thread until the request is complete and the response has been sent. ASP.NET 2.0 seeks to resolve latency issues with these types of issues by adding the capability to execute pages asynchronously. That means that a worker thread can start the request and then hand off additional execution to another thread, thereby returning to the available thread pool quickly. When the file IO, database call, etc. has completed, a new thread is obtained from the thread pool to finish the request. <br /> <br />The first step in making a page execute asynchronously is to set the Async attribute of the page directive like so: <br /> <br /><%@ Page Async="true" %> <br />This attribute tells ASP.NET to implement the IHttpAsyncHandler for the page. <br /> <br />The next step is to call the AddOnPreRenderCompleteAsync method at a point in the lifecycle of the page prior to PreRender. (This method is typically called in Page_Load.) The AddOnPreRenderCompleteAsync method takes two parameters; a BeginEventHandler and an EndEventHandler. The BeginEventHandler returns an IAsyncResult which is then passed as a parameter to the EndEventHandler. <br /> <br />The video below is a walkthrough of an asynchronous page request. <br /> <br /> <br />Open Full-Screen Video <br /> <br />Note: An async page does not render to the browser until the EndEventHandler has completed. No doubt but that some developers will think of async requests as being similar to async callbacks. It's important to realize that they are not. The benefit to asynchronous requests is that the first worker thread can be returned to the thread pool to service new requests, thereby reducing contention due to being IO bound, etc. <br /> <br />Script Callbacks in ASP.NET 2.0 <br />Web developers have always looked for ways to prevent the flickering associated with a callback. In ASP.NET 1.x, SmartNavigation was the most common method for avoiding flickering, but SmartNavigation caused problems for some developers because of the complexity of its implementation on the client. ASP.NET 2.0 addresses this issue with script callbacks. Script callbacks utilize XMLHttp to make requests against the Web server via JavaScript. The XMLHttp request returns XML data that can then be manipulated via the browser's DOM. XMLHttp code is hidden from the user by the new WebResource.axd handler. <br /> <br />There are several steps that are necessary in order to configure a script callback in ASP.NET 2.0. <br /> <br />Step 1 : Implement the ICallbackEventHandler Interface <br />In order for ASP.NET to recognize your page as participating in a script callback, you must implement the ICallbackEventHandler interface. You can do this in your code-behind file like so: <br /> <br />public partial class _Default : System.Web.UI.Page, ICallbackEventHandler <br />You can also do this using the @ Implements directive like so: <br /> <br /><%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %> <br />You would typically use the @ Implements directive when using inline ASP.NET code. <br /> <br />Step 2 : Call GetCallbackEventReference <br />As mentioned previously, the XMLHttp call is encapsulated in the WebResource.axd handler. When your page is rendered, ASP.NET will add a call to WebForm_DoCallback, a client script that is provided by WebResource.axd. The WebForm_DoCallback function replaces the __doPostBack function for a callback. Remember that __doPostBack programmatically submits the form on the page. In a callback scenario, you want to prevent a postback, so __doPostBack will not suffice. <br /> <br />Note: __doPostBack is still rendered to the page in a client script callback scenario. However, it's not used for the callback. <br /> <br />The arguments for the WebForm_DoCallback client-side function are provided via the server-side function GetCallbackEventReference which would normally be called in Page_Load. A typical call to GetCallbackEventReference might look like this: <br /> <br />// Set up the JavaScript callback <br />string cbRef = cm.GetCallbackEventReference(this, <br /> "document.getElementById('ddlCompany').value", <br /> "ShowCompanyName", "null", true); <br />Note: In this case, cm is an instance of ClientScriptManager. The ClientScriptManager class will be covered later in this module. <br /> <br />There are several overloaded versions of GetCallbackEventReference. In this case, the arguments are as follows: <br /> <br />this <br /> <br />A reference to the control where GetCallbackEventReference is being called. In this case, it's the page itself. <br /> <br />document.getElementById('ddlCompany').value <br /> <br />A string argument that will be passed from the client-side code to the server-side event. In this case, Im passing the value of a dropdown called ddlCompany. <br /> <br />ShowCompanyName <br /> <br />The name of the client-side function that will accept the return value (as string) from the server-side callback event. This function will only be called when the server-side callback is successful. Therefore, for the sake of robustness, it is generally recommended to use the overloaded version of GetCallbackEventReference that takes an additional string argument specifying the name of a client-side function to execute in the event of an error. <br /> <br />null <br /> <br />A string representing a client-side function that it initiated before the callback to the server. In this case, there is no such script, so the argument is null. <br /> <br />true <br /> <br />A Boolean specifying whether or not to conduct the callback asynchronously. <br /> <br />The call to WebForm_DoCallback on the client will pass these arguments. Therefore, when this page is rendered on the client, that code will look like so: <br /> <br />WebForm_DoCallback('__Page',document.getElementById('ddlCompany').value, <br /> ShowCompanyName,null,null,true) <br />Notice that the signature of the function on the client is a bit different. The client-side function passes 5 strings and a Boolean. The additional string (which is null in the above example) contains the client-side function that will handle any errors from the server-side callback. <br /> <br />Step 3 : Hook the Client-Side Control Event <br />Notice that the return value of GetCallbackEventReference above was assigned to a string variable. That string is used to hook a client-side event for the control that initiates the callback. In this example, the callback is initiated by a dropdown on the page, so I want to hook the OnChange event. <br /> <br />To hook the client-side event, simply add a handler to the client-side markup as follows: <br /> <br />// Hook the JavaScript function to the onchange event of the dropdown <br />ddlCompany.Attributes["onchange"] = <br /> String.Format("javascript:{0}", cbRef); <br />Recall that cbRef is the return value from the call to GetCallbackEventReference. It contains the call to WebForm_DoCallback that was shown above. <br /> <br />Step 4 : Register the Client-Side Script <br />Recall that the call to GetCallbackEventReference specified that a client-side script called ShowCompanyName would be executed when the server-side callback succeeds. That script needs to be added to the page using a ClientScriptManager instance. (The ClientScriptManager class will be dicussed later in this module.) You do that like so: <br /> <br />System.Text.StringBuilder clientScript = <br /> new System.Text.StringBuilder(""); <br />ClientScriptManager cm = Page.ClientScript; <br />// Create the client script <br />clientScript.Append("function ShowCompanyName(companyName)"); <br />clientScript.Append("{"); <br />clientScript.Append("document.getElementById('CoClicked').innerHTML = <br /> \"You chose \" + companyName + \".\";"); <br />clientScript.Append("}"); <br />cm.RegisterClientScriptBlock(this.GetType(), <br /> "showCo", clientScript.ToString(), true); <br />Step 5 : Call the Methods of the ICallbackEventHandler Interface <br />The ICallbackEventHandler contains two methods that you need to implement in your code. They are RaiseCallbackEvent and GetCallbackEvent. <br /> <br />RaiseCallbackEvent takes a string as an argument and returns nothing. The string argument is passed from the client-side call to WebForm_DoCallback. In this case, that value is the value attribute of the dropdown called ddlCompany. Your server-side code should be placed in the RaiseCallbackEvent method. For example, if your callback is making a WebRequest against an external resource, that code should be placed in RaiseCallbackEvent. <br /> <br />GetCallbackEvent is responsible for processing the return of the callback to the client. It takes no arguments and returns a string. The string that it returns will be passed as an argument to the client-side function, in this case ShowCompanyName. <br /> <br />Once you have completed the above steps, you are ready to perform a script callback in ASP.NET 2.0. <br /> <br /> <br />Open Full-Screen Video <br /> <br />Script callbacks in ASP.NET are supported in any browser that supports making XMLHttp calls. That includes all of the modern browsers in use today. Internet Explorer uses the XMLHttp ActiveX object while other modern browsers (including the upcoming IE 7) use an intrinsic XMLHttp object. To programmatically determine if a browser supports callbacks, you can use the Request.Browser.SupportCallback property. This property will return true if the requesting client supports script callbacks. <br /> <br />Working with Client Script in ASP.NET 2.0 <br />Client scripts in ASP.NET 2.0 are managed via the use of the ClientScriptManager class. The ClientScriptManager class keeps track of client scripts using a type and a name. This prevents the same script from being programmatically inserted on a page more than once. <br /> <br />Note: After a script has been successfully registered on a page, any subsequent attempt to register the same script will simply result in the script not being registered a second time. No duplicate scripts are added and no exception occurs. To avoid unnecessary computation, there are methods that you can use to determine if a script is already registered so that you do not attempt to register it more than once. <br /> <br />The methods of the ClientScriptManager should be familiar to all current ASP.NET developers: <br /> <br />RegisterClientScriptBlock <br />This method adds a script to the top of the rendered page. This is useful for adding functions that will be explicitly called on the client. <br /> <br />There are two overloaded versions of this method. Three of four arguments are common among them. They are: <br /> <br />type (string) <br /> <br />The type argument identifies a type for the script. It is generally a good idea to use the page's type (this.GetType()) for the type. <br /> <br />key (string) <br /> <br />The key argument is a user-defined key for the script. This should be unique for each script. If you attempt to add a script with the same key and type of an already added script, it will not be added. <br /> <br />script (string) <br /> <br />The script argument is a string containing the actual script to add. It's recommended that you use a StringBuilder to create the script and then use the ToString() method on the StringBuilder to assign the script argument. <br /> <br />If you use the overloaded RegisterClientScriptBlock that only takes three arguments, you must include script elements (<script> and </script>) in your script. <br /> <br />You may choose to use the overload of RegisterClientScriptBlock that takes a fourth argument. The fourth argument is a Boolean that specifies whether or not ASP.NET should add script elements for you. If this argument is true, your script should not include the script elements explicitly. <br /> <br />Use the IsClientScriptBlockRegistered method to determine if a script has already been registered. This allows you to avoid an attempt to re-register a script that has already been registered. <br /> <br />RegisterClientScriptInclude (New in 2.0) <br />The RegisterClientScriptInclude tag creates a script block that links to an external script file. It has two overloads. One takes a key and a URL. The second adds a third argument specifying the type. <br /> <br />For example, the following code generates a script block that links to jsfunctions.js in the root of the scripts folder of the application: <br /> <br />ClientScriptManager cm = Page.ClientScript; <br />if(!cm.IsClientScriptIncludeRegistered("jsfunc")) { <br /> cm.RegisterClientScriptInclude(this.GetType(), <br /> "jsfunc", "/scripts/jsfunctions.js"); <br /> } <br />This code produces the following code in the rendered page: <br /> <br /><script src="/scripts/jsfunctions.js" <br /> type="text/javascript"></script> <br />Note: The script block is rendered at the bottom of the page. <br /> <br />Use the IsClientScriptIncludeRegistered method to determine if a script has already been registered. This allows you to avoid an attempt to re-register a script. <br /> <br />RegisterStartupScript <br />The RegisterStartupScript method takes the same arguments as the RegisterClientScriptBlock method. A script registered with RegisterStartupScript executes after the page loads but before the OnLoad client-side event. In 1.X, scripts registered with RegisterStartupScript were placed just before the closing </form> tag while scripts registered with RegisterClientScriptBlock were placed immediately after the opening <form> tag. In ASP.NET 2.0, both are placed immediately before the closing </form> tag. <br /> <br />Note: If you register a function with RegisterStartupScript, that function will not execute until you explicitly call it in client-side code. <br /> <br />Use the IsStartupScriptRegistered method to determine if a script has already been registered and avoid an attempt to re-register a script. <br /> <br />Other ClientScriptManager Methods <br />Here are some of the other useful methods of the ClientScriptManager class. <br /> <br />GetCallbackEventReference See script callbacks earlier in this module. <br />GetPostBackClientHyperlink Gets a JavaScript reference (javascript:<call>) that can be used to post back from a client-side event. <br />GetPostBackEventReference Gets a string that can be used to initiate a post back from the client. <br />GetWebResourceUrl Returns a URL to a resource that is embedded in an assembly. Must be used in conjunction with RegisterClientScriptResource. <br />RegisterClientScriptResource Registers a Web resource with the page. These are resources embedded in an assembly and handled by the new WebResource.axd handler. <br />RegisterHiddenField Registers a hidden form field with the page. <br />RegisterOnSubmitStatement Registers client-side code that executes when the HTML form is submitted. <br /> <div style='clear: both;'></div> </div> <div class='post-footer'> <div class='post-footer-line post-footer-line-1'> <span class='post-author vcard'> Posted by <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://www.blogger.com/profile/09922623341230260301' itemprop='url'/> <a class='g-profile' href='https://www.blogger.com/profile/09922623341230260301' rel='author' title='author profile'> <span itemprop='name'>siddharth</span> </a> </span> </span> <span class='post-timestamp'> at <meta content='http://siddharthpanchal.blogspot.com/2008/07/aspnet-20-page-model.html' itemprop='url'/> <a class='timestamp-link' href='https://siddharthpanchal.blogspot.com/2008/07/aspnet-20-page-model.html' rel='bookmark' title='permanent link'><abbr class='published' itemprop='datePublished' title='2008-07-29T00:54:00-07:00'>12:54 AM</abbr></a> </span> <span class='post-comment-link'> <a class='comment-link' href='https://www.blogger.com/comment/fullpage/post/8811631391201505101/6545575501095849666' onclick=''> No comments: </a> </span> <span class='post-icons'> <span class='item-action'> <a href='https://www.blogger.com/email-post.g?blogID=8811631391201505101&postID=6545575501095849666' title='Email Post'> <img alt='' class='icon-action' height='13' src='https://resources.blogblog.com/img/icon18_email.gif' width='18'/> </a> </span> <span class='item-control blog-admin pid-147730082'> <a href='https://www.blogger.com/post-edit.g?blogID=8811631391201505101&postID=6545575501095849666&from=pencil' title='Edit Post'> <img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/> </a> </span> </span> <div class='post-share-buttons goog-inline-block'> </div> </div> <div class='post-footer-line post-footer-line-2'> <span class='post-labels'> </span> </div> <div class='post-footer-line post-footer-line-3'> <span class='post-location'> </span> </div> </div> </div> </div> </div></div> </div> <div class='blog-pager' id='blog-pager'> <span id='blog-pager-newer-link'> <a class='blog-pager-newer-link' href='https://siddharthpanchal.blogspot.com/search?updated-max=2008-09-22T07:23:00-07:00&max-results=7&reverse-paginate=true' id='Blog1_blog-pager-newer-link' title='Newer Posts'>Newer Posts</a> </span> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='https://siddharthpanchal.blogspot.com/search?updated-max=2008-07-29T00:54:00-07:00&max-results=7' id='Blog1_blog-pager-older-link' title='Older Posts'>Older Posts</a> </span> <a class='home-link' href='https://siddharthpanchal.blogspot.com/'>Home</a> </div> <div class='clear'></div> <div class='blog-feeds'> <div class='feed-links'> Subscribe to: <a class='feed-link' href='https://siddharthpanchal.blogspot.com/feeds/posts/default' target='_blank' type='application/atom+xml'>Posts (Atom)</a> </div> </div> </div><div class='widget BlogList' data-version='1' id='BlogList1'> <h2 class='title'>My Blog List</h2> <div class='widget-content'> <div class='blog-list-container' id='BlogList1_container'> <ul id='BlogList1_blogs'> <li style='display: block;'> <div class='blog-icon'> <img data-lateloadsrc='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_s0LGdMbvaJd1Lj_6cXgIjsFZgoA-0-rSdrFarjLA3w5x079RSJsn3XOFgj1pfUNYZ6I7bpr5qsUPGKxbknyaRHJA1RsSEj951FcmSt=s16-w16-h16' height='16' width='16'/> </div> <div class='blog-content'> <div class='blog-title'> <a href='http://systadmin.blogspot.com/feeds/posts/default' target='_blank'> Network Administrator,tips to secure DNS,dhcp,active directory,exchange server,</a> </div> <div class='item-content'> <span class='item-title'> <!--Can't find substitution for tag [item.itemTitle]--> </span> - <span class='item-snippet'> <!--Can't find substitution for tag [item.itemSnippet]--> </span> <div class='item-time'> <!--Can't find substitution for tag [item.timePeriodSinceLastUpdate]--> </div> </div> </div> <div style='clear: both;'></div> </li> </ul> <div class='clear'></div> </div> </div> </div></div> </div> <div id='sidebar-wrapper'> <div class='sidebar section' id='sidebar'><div class='widget HTML' data-version='1' id='HTML3'> <h2 class='title'>Search with power Google</h2> <div class='widget-content'> <form id="cse-search-box" action="http://siddharthpanchal.blogspot.com/"> <div> <input value="partner-pub-4977731271124642:4kmkrk-q739" name="cx" type="hidden"/> <input value="FORID:10" name="cof" type="hidden"/> <input value="ISO-8859-1" name="ie" type="hidden"/> <input name="q" size="31" type="text"/> <input value="Search" name="sa" type="submit"/> </div> </form> <script src="/cse/brand?form=cse-search-box&lang=en" type="text/javascript"></script> </div> <div class='clear'></div> </div><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <h2>Blog Archive</h2> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2011/'> 2011 </a> <span class='post-count' dir='ltr'>(4)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2011/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2011/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2011/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2009/'> 2009 </a> <span class='post-count' dir='ltr'>(6)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2009/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2009/02/'> February </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> ▼  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2008/'> 2008 </a> <span class='post-count' dir='ltr'>(50)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2008/09/'> September </a> <span class='post-count' dir='ltr'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2008/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> ▼  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2008/07/'> July </a> <span class='post-count' dir='ltr'>(24)</span> <ul class='posts'> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/this-is-ultimate-grid-from-etcjscom.html'>This is ultimate grid from etcjs.com site a totall...</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/extending-linq-class.html'>Extending Linq class</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/why-constructors.html'>Why Constructors?</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/class-modifiers-and-their-uses-in-c-net.html'>Class Modifiers and their uses in C# .Net</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/difference-between-class-and-struct-in.html'>Difference between class and struct in C# .Net</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/captcha-class-for-c-developer.html'>captcha class for c# developer</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/compress-aspx-pagesthrough-this-class.html'>compress a ASPX pagesthrough this class</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/best-perfomance-in-linq-query.html'>best perfomance in LINQ query</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/asynchronous-pages-in-aspnet-20.html'>Asynchronous Pages in ASP.NET 2.0</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/aspnet-20-page-model.html'>The ASP.NET 2.0 Page Model</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/arraysegment-structure-what-were-they.html'>ArraySegment Structure - what were they thinking?</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/pagebase-class-for-each-web-site-you.html'>Pagebase class for each web site you must include ...</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/inline-search-query-easy-to-code-and.html'>inline search query easy to code and perfomeance b...</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/too-good-slideshow-url.html'>Too good SLIDESHOW url</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/tracing-overview.html'>Tracing Overview</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/mts-transactions.html'>MTS Transactions</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/simple-utility-class-which-we-need-in.html'>simple utility class which we need in each and eve...</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/what-is-xslt-how-it-used-in-code.html'>what is XSLT how it used in code</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/pdf-generate-with-help-of-abc-pdf-dll.html'>PDF generate with help of ABC pdf dll</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/resize-image-automatically-cool-class.html'>resize image automatically cool class</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/url-rewrite-module.html'>URL rewrite module</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/linq-sqlhelper.html'>LINQ sqlhelper</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/what-is-json.html'>what is JSON ?</a></li> <li><a href='https://siddharthpanchal.blogspot.com/2008/07/animation-effect.html'>Animation effect</a></li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2008/06/'> June </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://siddharthpanchal.blogspot.com/2008/04/'> April </a> <span class='post-count' dir='ltr'>(13)</span> </li> </ul> </li> </ul> </div> </div> <div class='clear'></div> </div> </div><div class='widget TextList' data-version='1' id='TextList1'> <h2>LINQ to SQL</h2> <div class='widget-content'> <ul> <li><a href="http://www.devgroup-stuttgart.de/Download/2006-10-25/CS3.0andLinqFinal.pdf" target="_new">C# 3.0 and Linq Final.ppt</a></li> </ul> <div class='clear'></div> </div> </div><div class='widget Subscribe' data-version='1' id='Subscribe1'> <div style='white-space:nowrap'> <h2 class='title'>Subscribe To</h2> <div class='widget-content'> <div class='subscribe-wrapper subscribe-type-POST'> <div class='subscribe expanded subscribe-type-POST' id='SW_READER_LIST_Subscribe1POST' style='display:none;'> <div class='top'> <span class='inner' onclick='return(_SW_toggleReaderList(event, "Subscribe1POST"));'> <img class='subscribe-dropdown-arrow' src='https://resources.blogblog.com/img/widgets/arrow_dropdown.gif'/> <img align='absmiddle' alt='' border='0' class='feed-icon' src='https://resources.blogblog.com/img/icon_feed12.png'/> Posts </span> <div class='feed-reader-links'> <a class='feed-reader-link' href='https://www.netvibes.com/subscribe.php?url=https%3A%2F%2Fsiddharthpanchal.blogspot.com%2Ffeeds%2Fposts%2Fdefault' target='_blank'> <img src='https://resources.blogblog.com/img/widgets/subscribe-netvibes.png'/> </a> <a class='feed-reader-link' href='https://add.my.yahoo.com/content?url=https%3A%2F%2Fsiddharthpanchal.blogspot.com%2Ffeeds%2Fposts%2Fdefault' target='_blank'> <img src='https://resources.blogblog.com/img/widgets/subscribe-yahoo.png'/> </a> <a class='feed-reader-link' href='https://siddharthpanchal.blogspot.com/feeds/posts/default' target='_blank'> <img align='absmiddle' class='feed-icon' src='https://resources.blogblog.com/img/icon_feed12.png'/> Atom </a> </div> </div> <div class='bottom'></div> </div> <div class='subscribe' id='SW_READER_LIST_CLOSED_Subscribe1POST' onclick='return(_SW_toggleReaderList(event, "Subscribe1POST"));'> <div class='top'> <span class='inner'> <img class='subscribe-dropdown-arrow' src='https://resources.blogblog.com/img/widgets/arrow_dropdown.gif'/> <span onclick='return(_SW_toggleReaderList(event, "Subscribe1POST"));'> <img align='absmiddle' alt='' border='0' class='feed-icon' src='https://resources.blogblog.com/img/icon_feed12.png'/> Posts </span> </span> </div> <div class='bottom'></div> </div> </div> <div class='subscribe-wrapper subscribe-type-COMMENT'> <div class='subscribe expanded subscribe-type-COMMENT' id='SW_READER_LIST_Subscribe1COMMENT' style='display:none;'> <div class='top'> <span class='inner' onclick='return(_SW_toggleReaderList(event, "Subscribe1COMMENT"));'> <img class='subscribe-dropdown-arrow' src='https://resources.blogblog.com/img/widgets/arrow_dropdown.gif'/> <img align='absmiddle' alt='' border='0' class='feed-icon' src='https://resources.blogblog.com/img/icon_feed12.png'/> All Comments </span> <div class='feed-reader-links'> <a class='feed-reader-link' href='https://www.netvibes.com/subscribe.php?url=https%3A%2F%2Fsiddharthpanchal.blogspot.com%2Ffeeds%2Fcomments%2Fdefault' target='_blank'> <img src='https://resources.blogblog.com/img/widgets/subscribe-netvibes.png'/> </a> <a class='feed-reader-link' href='https://add.my.yahoo.com/content?url=https%3A%2F%2Fsiddharthpanchal.blogspot.com%2Ffeeds%2Fcomments%2Fdefault' target='_blank'> <img src='https://resources.blogblog.com/img/widgets/subscribe-yahoo.png'/> </a> <a class='feed-reader-link' href='https://siddharthpanchal.blogspot.com/feeds/comments/default' target='_blank'> <img align='absmiddle' class='feed-icon' src='https://resources.blogblog.com/img/icon_feed12.png'/> Atom </a> </div> </div> <div class='bottom'></div> </div> <div class='subscribe' id='SW_READER_LIST_CLOSED_Subscribe1COMMENT' onclick='return(_SW_toggleReaderList(event, "Subscribe1COMMENT"));'> <div class='top'> <span class='inner'> <img class='subscribe-dropdown-arrow' src='https://resources.blogblog.com/img/widgets/arrow_dropdown.gif'/> <span onclick='return(_SW_toggleReaderList(event, "Subscribe1COMMENT"));'> <img align='absmiddle' alt='' border='0' class='feed-icon' src='https://resources.blogblog.com/img/icon_feed12.png'/> All Comments </span> </span> </div> <div class='bottom'></div> </div> </div> <div style='clear:both'></div> </div> </div> <div class='clear'></div> </div><div class='widget Profile' data-version='1' id='Profile1'> <h2>About Me</h2> <div class='widget-content'> <a href='https://www.blogger.com/profile/09922623341230260301'><img alt='My photo' class='profile-img' height='80' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuF9V0Wltv5WtPnu4r54_U0a3WtPMbhjYvU20987SxqI6JJ9xuDjJC_gAFtzZDhI-1Wzr9iyYa1y54leqKX5xPY77MQvc08O8urW621Li1IVwla-vd-01hbTipCAZo/s220/Untitled.jpg' width='74'/></a> <dl class='profile-datablock'> <dt class='profile-data'> <a class='profile-name-link g-profile' href='https://www.blogger.com/profile/09922623341230260301' rel='author' style='background-image: url(//www.blogger.com/img/logo-16.png);'> siddharth </a> </dt> <dd class='profile-textblock'>Life is all about change</dd> </dl> <a class='profile-link' href='https://www.blogger.com/profile/09922623341230260301' rel='author'>View my complete profile</a> <div class='clear'></div> </div> </div><div class='widget Followers' data-version='1' id='Followers1'> <h2 class='title'>Followers</h2> <div class='widget-content'> <div id='Followers1-wrapper'> <div style='margin-right:2px;'> <div><script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <div id="followers-iframe-container"></div> <script type="text/javascript"> window.followersIframe = null; function followersIframeOpen(url) { gapi.load("gapi.iframes", function() { if (gapi.iframes && gapi.iframes.getContext) { window.followersIframe = gapi.iframes.getContext().openChild({ url: url, where: document.getElementById("followers-iframe-container"), messageHandlersFilter: gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER, messageHandlers: { '_ready': function(obj) { window.followersIframe.getIframeEl().height = obj.height; }, 'reset': function() { window.followersIframe.close(); followersIframeOpen("https://www.blogger.com/followers/frame/8811631391201505101?colors\x3dCgt0cmFuc3BhcmVudBILdHJhbnNwYXJlbnQaByMwMDAwMDAiByMwMDAwZmYqByNmNWY1ZjUyByMwMDAwMDA6ByMwMDAwMDBCByMwMDAwZmZKByMwMDAwMDBSByMwMDAwZmZaC3RyYW5zcGFyZW50\x26pageSize\x3d21\x26hl\x3den\x26origin\x3dhttps://siddharthpanchal.blogspot.com"); }, 'open': function(url) { window.followersIframe.close(); followersIframeOpen(url); }, 'blogger-ping': function() { } } }); } }); } followersIframeOpen("https://www.blogger.com/followers/frame/8811631391201505101?colors\x3dCgt0cmFuc3BhcmVudBILdHJhbnNwYXJlbnQaByMwMDAwMDAiByMwMDAwZmYqByNmNWY1ZjUyByMwMDAwMDA6ByMwMDAwMDBCByMwMDAwZmZKByMwMDAwMDBSByMwMDAwZmZaC3RyYW5zcGFyZW50\x26pageSize\x3d21\x26hl\x3den\x26origin\x3dhttps://siddharthpanchal.blogspot.com"); </script></div> </div> </div> <div class='clear'></div> </div> </div><div class='widget BloggerButton' data-version='1' id='BloggerButton1'> <div class='widget-content'> <a href='https://www.blogger.com'><img alt='Powered By Blogger' src='https://www.blogger.com/buttons/blogger-ipower-kahki.gif'/></a> <div class='clear'></div> </div> </div><div class='widget HTML' data-version='1' id='HTML1'> <div class='widget-content'> <script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </script> <script type="text/javascript"> try { var pageTracker = _gat._getTracker("UA-3165944-3"); pageTracker._trackPageview(); } catch(err) {}</script> </div> <div class='clear'></div> </div></div> </div> <!-- spacer for skins that want sidebar and main to be the same height--> <div class='clear'> </div> </div> <!-- end content-wrapper --> </div></div> <!-- end outer-wrapper --> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/1926661341-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY6vvOPU9XzBK-qVtb8d0B4D929evg:1729222215036';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d8811631391201505101','//siddharthpanchal.blogspot.com/2008/07/','8811631391201505101'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '8811631391201505101', 'title': 'siddharth \x22Nothing is permanent \x22', 'url': 'https://siddharthpanchal.blogspot.com/2008/07/', 'canonicalUrl': 'http://siddharthpanchal.blogspot.com/2008/07/', 'homepageUrl': 'https://siddharthpanchal.blogspot.com/', 'searchUrl': 'https://siddharthpanchal.blogspot.com/search', 'canonicalHomepageUrl': 'http://siddharthpanchal.blogspot.com/', 'blogspotFaviconUrl': 'https://siddharthpanchal.blogspot.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': false, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': '', 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22siddharth \x26quot;Nothing is permanent \x26quot; - Atom\x22 href\x3d\x22https://siddharthpanchal.blogspot.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22siddharth \x26quot;Nothing is permanent \x26quot; - RSS\x22 href\x3d\x22https://siddharthpanchal.blogspot.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22siddharth \x26quot;Nothing is permanent \x26quot; - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/8811631391201505101/posts/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/f220f96f12fba80a', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'Twitter', 'key': 'twitter', 'shareMessage': 'Share to Twitter', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'archive', 'pageName': 'July 2008', 'pageTitle': 'siddharth \x22Nothing is permanent \x22: July 2008'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'isResponsive': false, 'isAlternateRendering': false, 'isCustom': false}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'siddharth \x22Nothing is permanent \x22', 'description': '', 'url': 'https://siddharthpanchal.blogspot.com/2008/07/', 'type': 'feed', 'isSingleItem': false, 'isMultipleItems': true, 'isError': false, 'isPage': false, 'isPost': false, 'isHomepage': false, 'isArchive': true, 'isLabelSearch': false, 'archive': {'year': 2008, 'month': 7, 'rangeMessage': 'Showing posts from July, 2008'}}}]); _WidgetManager._RegisterWidget('_NavbarView', new _WidgetInfo('Navbar1', 'navbar', document.getElementById('Navbar1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'main', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'lightboxEnabled': true, 'lightboxModuleUrl': 'https://www.blogger.com/static/v1/jsbin/832967572-lbx.js', 'lightboxCssUrl': 'https://www.blogger.com/static/v1/v-css/13464135-lightbox_bundle.css'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogListView', new _WidgetInfo('BlogList1', 'main', document.getElementById('BlogList1'), {'numItemsToShow': 0, 'totalItems': 1}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML3', 'sidebar', document.getElementById('HTML3'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_TextListView', new _WidgetInfo('TextList1', 'sidebar', document.getElementById('TextList1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_SubscribeView', new _WidgetInfo('Subscribe1', 'sidebar', document.getElementById('Subscribe1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_ProfileView', new _WidgetInfo('Profile1', 'sidebar', document.getElementById('Profile1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_FollowersView', new _WidgetInfo('Followers1', 'sidebar', document.getElementById('Followers1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BloggerButtonView', new _WidgetInfo('BloggerButton1', 'sidebar', document.getElementById('BloggerButton1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML1', 'sidebar', document.getElementById('HTML1'), {}, 'displayModeFull')); </script> </body> </html>