Adding custom events
to asp.net composite custom control - Part 116
Suggested Videos
Part 113 - Adding composite custom controls to visual studio tool box
Part 114 - Adding properties to composite custom controls
Part 115 - Solving the problems of asp.net composite custom calendar control
In this video we will discuss about adding custom event to the asp.net composite custom calendar control that we have been working with from Parts 112 to 115. Please watch Parts 112 to 115 from the asp.net video tutorial before proceeding with this video.
We have discussed about adding custom events to user controls in Parts 106 to 108. You can watch these videos from the asp.net video tutorial. Adding custom events to a composite control is similar to adding events to user controls.
There are 5 simple steps to add "DateSelected" custom event to composite custom calendar control
Step 1: Create "DateSelectedEventArgs" that will contain event data
public class DateSelectedEventArgs : EventArgs
{
private DateTime _selectedDate;
public DateSelectedEventArgs(DateTime selectedDate)
{
this._selectedDate = selectedDate;
}
public DateTime SelectedDate
{
get
{
return this._selectedDate;
}
}
}
Step 2: Create "DateSelectedEventHandler" delegate
public delegate void DateSelectedEventHandler(object sender, DateSelectedEventArgs e);
Step 3: Create "DateSelected" event.
public event DateSelectedEventHandler DateSelected;
Step 4: Create a protected virtual method to raise the event.
protected virtual void OnDateSelection(DateSelectedEventArgs e)
{
if (DateSelected != null)
{
DateSelected(this, e);
}
}
Step 5: Finally raise the event, when the date selection in the calendar changes.
DateSelectedEventArgs dateSelectedEventData = new DateSelectedEventArgs(calendar.SelectedDate);
OnDateSelection(dateSelectedEventData);
Here is the complete code of the composite custom calendar control:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CustomControls
{
[ToolboxData("<{0}:CustomCalendar runat=server></{0}:CustomCalendar>")]
public class CustomCalendar : CompositeControl
{
TextBox textBox;
ImageButton imageButton;
Calendar calendar;
protected override void CreateChildControls()
{
Controls.Clear();
textBox = new TextBox();
textBox.ID = "dateTextBox";
textBox.Width = Unit.Pixel(80);
imageButton = new ImageButton();
imageButton.ID = "calendarImageButton";
imageButton.Click += new ImageClickEventHandler(imageButton_Click);
calendar = new Calendar();
calendar.ID = "calendarControl";
calendar.SelectionChanged += new EventHandler(calendar_SelectionChanged);
calendar.Visible = false;
this.Controls.Add(textBox);
this.Controls.Add(imageButton);
this.Controls.Add(calendar);
}
void calendar_SelectionChanged(object sender, EventArgs e)
{
textBox.Text = calendar.SelectedDate.ToShortDateString();
DateSelectedEventArgs dateSelectedEventData = new DateSelectedEventArgs(calendar.SelectedDate);
OnDateSelection(dateSelectedEventData);
calendar.Visible = false;
}
void imageButton_Click(object sender, ImageClickEventArgs e)
{
if (calendar.Visible)
{
calendar.Visible = false;
}
else
{
calendar.Visible = true;
if (string.IsNullOrEmpty(textBox.Text))
{
calendar.VisibleDate = DateTime.Today;
}
else
{
DateTime output = DateTime.Today;
bool isDateTimeConverionSuccessful = DateTime.TryParse(textBox.Text, out output);
calendar.VisibleDate = output;
}
}
}
[Category("Appearance")]
[Description("Sets the image icon for the calendar control")]
public string ImageButtonImageUrl
{
get
{
EnsureChildControls();
return imageButton.ImageUrl != null ? imageButton.ImageUrl : string.Empty;
}
set
{
EnsureChildControls();
imageButton.ImageUrl = value;
}
}
[Category("Appearance")]
[Description("Gets or sets the selected date of custom calendar control")]
public DateTime SelectedDate
{
get
{
EnsureChildControls();
return string.IsNullOrEmpty(textBox.Text) ? DateTime.MinValue : Convert.ToDateTime(textBox.Text);
}
set
{
if (value != null)
{
EnsureChildControls();
textBox.Text = value.ToShortDateString();
}
else
{
EnsureChildControls();
textBox.Text = "";
}
}
}
protected override void RecreateChildControls()
{
EnsureChildControls();
}
protected override void Render(HtmlTextWriter writer)
{
AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "1");
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
textBox.RenderControl(writer);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
imageButton.RenderControl(writer);
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
calendar.RenderControl(writer);
}
public event DateSelectedEventHandler DateSelected;
protected virtual void OnDateSelection(DateSelectedEventArgs e)
{
if (DateSelected != null)
{
DateSelected(this, e);
}
}
}
public class DateSelectedEventArgs : EventArgs
{
private DateTime _selectedDate;
public DateSelectedEventArgs(DateTime selectedDate)
{
this._selectedDate = selectedDate;
}
public DateTime SelectedDate
{
get
{
return this._selectedDate;
}
}
}
public delegate void DateSelectedEventHandler(object sender, DateSelectedEventArgs e);
}
Build the CustomControls project. In an asp.net web application add a reference to the CustomCalendar control. Drag and drop the CustomCalendar control on a webform. Right click on the control and select properties. In the properties window, click on the events icon. Notice that, the event "DateSelected" is displayed.

Double click on the "DateSelected" event. This should automatically generate an event handler method. Implement the event handler method as shown below.
protected void CustomCalendar1_DateSelected(object sender, CustomControls.DateSelectedEventArgs e)
{
Response.Write(e.SelectedDate.ToShortDateString());
}
Please run the project, and test.
Part 113 - Adding composite custom controls to visual studio tool box
Part 114 - Adding properties to composite custom controls
Part 115 - Solving the problems of asp.net composite custom calendar control
In this video we will discuss about adding custom event to the asp.net composite custom calendar control that we have been working with from Parts 112 to 115. Please watch Parts 112 to 115 from the asp.net video tutorial before proceeding with this video.
We have discussed about adding custom events to user controls in Parts 106 to 108. You can watch these videos from the asp.net video tutorial. Adding custom events to a composite control is similar to adding events to user controls.
There are 5 simple steps to add "DateSelected" custom event to composite custom calendar control
Step 1: Create "DateSelectedEventArgs" that will contain event data
public class DateSelectedEventArgs : EventArgs
{
private DateTime _selectedDate;
public DateSelectedEventArgs(DateTime selectedDate)
{
this._selectedDate = selectedDate;
}
public DateTime SelectedDate
{
get
{
return this._selectedDate;
}
}
}
Step 2: Create "DateSelectedEventHandler" delegate
public delegate void DateSelectedEventHandler(object sender, DateSelectedEventArgs e);
Step 3: Create "DateSelected" event.
public event DateSelectedEventHandler DateSelected;
Step 4: Create a protected virtual method to raise the event.
protected virtual void OnDateSelection(DateSelectedEventArgs e)
{
if (DateSelected != null)
{
DateSelected(this, e);
}
}
Step 5: Finally raise the event, when the date selection in the calendar changes.
DateSelectedEventArgs dateSelectedEventData = new DateSelectedEventArgs(calendar.SelectedDate);
OnDateSelection(dateSelectedEventData);
Here is the complete code of the composite custom calendar control:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CustomControls
{
[ToolboxData("<{0}:CustomCalendar runat=server></{0}:CustomCalendar>")]
public class CustomCalendar : CompositeControl
{
TextBox textBox;
ImageButton imageButton;
Calendar calendar;
protected override void CreateChildControls()
{
Controls.Clear();
textBox = new TextBox();
textBox.ID = "dateTextBox";
textBox.Width = Unit.Pixel(80);
imageButton = new ImageButton();
imageButton.ID = "calendarImageButton";
imageButton.Click += new ImageClickEventHandler(imageButton_Click);
calendar = new Calendar();
calendar.ID = "calendarControl";
calendar.SelectionChanged += new EventHandler(calendar_SelectionChanged);
calendar.Visible = false;
this.Controls.Add(textBox);
this.Controls.Add(imageButton);
this.Controls.Add(calendar);
}
void calendar_SelectionChanged(object sender, EventArgs e)
{
textBox.Text = calendar.SelectedDate.ToShortDateString();
DateSelectedEventArgs dateSelectedEventData = new DateSelectedEventArgs(calendar.SelectedDate);
OnDateSelection(dateSelectedEventData);
calendar.Visible = false;
}
void imageButton_Click(object sender, ImageClickEventArgs e)
{
if (calendar.Visible)
{
calendar.Visible = false;
}
else
{
calendar.Visible = true;
if (string.IsNullOrEmpty(textBox.Text))
{
calendar.VisibleDate = DateTime.Today;
}
else
{
DateTime output = DateTime.Today;
bool isDateTimeConverionSuccessful = DateTime.TryParse(textBox.Text, out output);
calendar.VisibleDate = output;
}
}
}
[Category("Appearance")]
[Description("Sets the image icon for the calendar control")]
public string ImageButtonImageUrl
{
get
{
EnsureChildControls();
return imageButton.ImageUrl != null ? imageButton.ImageUrl : string.Empty;
}
set
{
EnsureChildControls();
imageButton.ImageUrl = value;
}
}
[Category("Appearance")]
[Description("Gets or sets the selected date of custom calendar control")]
public DateTime SelectedDate
{
get
{
EnsureChildControls();
return string.IsNullOrEmpty(textBox.Text) ? DateTime.MinValue : Convert.ToDateTime(textBox.Text);
}
set
{
if (value != null)
{
EnsureChildControls();
textBox.Text = value.ToShortDateString();
}
else
{
EnsureChildControls();
textBox.Text = "";
}
}
}
protected override void RecreateChildControls()
{
EnsureChildControls();
}
protected override void Render(HtmlTextWriter writer)
{
AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "1");
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
textBox.RenderControl(writer);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
imageButton.RenderControl(writer);
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
calendar.RenderControl(writer);
}
public event DateSelectedEventHandler DateSelected;
protected virtual void OnDateSelection(DateSelectedEventArgs e)
{
if (DateSelected != null)
{
DateSelected(this, e);
}
}
}
public class DateSelectedEventArgs : EventArgs
{
private DateTime _selectedDate;
public DateSelectedEventArgs(DateTime selectedDate)
{
this._selectedDate = selectedDate;
}
public DateTime SelectedDate
{
get
{
return this._selectedDate;
}
}
}
public delegate void DateSelectedEventHandler(object sender, DateSelectedEventArgs e);
}
Build the CustomControls project. In an asp.net web application add a reference to the CustomCalendar control. Drag and drop the CustomCalendar control on a webform. Right click on the control and select properties. In the properties window, click on the events icon. Notice that, the event "DateSelected" is displayed.

Double click on the "DateSelected" event. This should automatically generate an event handler method. Implement the event handler method as shown below.
protected void CustomCalendar1_DateSelected(object sender, CustomControls.DateSelectedEventArgs e)
{
Response.Write(e.SelectedDate.ToShortDateString());
}
Please run the project, and test.
Assigning an image to
the composite custom control in visual studio tool box - Part 117
Suggested Videos
Part 114 - Adding properties to composite custom controls
Part 115 - Solving the problems of asp.net composite custom calendar control
Part 116 - Adding custom events to asp.net composite custom control
In this video we will discuss about assigning an image to the Composite Custom calendar control in visual studio tool box. Please watch Parts 112 to 116 from the asp.net video tutorial before proceeding with this video.
To associate an image to the composite custom calendar control use ToolboxBitmap attribute. This attribute is present in System.Drawing namespace. There are 2 ways we can use this attribute.
Using ToolboxBitmap attribute to associate, the image of an existing control: In this example, we are assigning the image of the asp.net calendar control to the composite custom calendar control. Please notice the usage of ToolboxBitmap attribute with "typeof" keyword.
[System.Drawing.ToolboxBitmap(typeof(Calendar))]
[ToolboxData("<{0}:CustomCalendar runat=server></{0}:CustomCalendar>")]
public class CustomCalendar : CompositeControl
{
TextBox textBox;
ImageButton imageButton;
Calendar calendar;
// Rest of the code.....
}
Rebuild the CustomControls project. Re-add the CustomCalendar control to visual studio tool box and notice that the asp.net calendar control icon is also used for the CustomCalendar control.

Using ToolboxBitmap attribute to associate a custom image: Create an image measuring 16X16 pixels in dimensions. I have used Microsoft paint to come up with the custom image that you can see below.

Save this image to "C:\Images" folder or in a folder of your choice. I have given the name of "CustomCalendarIcon.bmp" to the image.
Finally use the ToolboxBitmap attribute and specify the path to the image.
[System.Drawing.ToolboxBitmap(@"C:\Images\CustomCalendarIcon.bmp")]
[ToolboxData("<{0}:CustomCalendar runat=server></{0}:CustomCalendar>")]
public class CustomCalendar : CompositeControl
{
TextBox textBox;
ImageButton imageButton;
Calendar calendar;
// Rest of the code.....
}
Rebuild the CustomControls project. Re-add the CustomCalendar control to visual studio tool box and notice that the custom image "CustomCalendarIcon.bmp" is used for the CustomCalendar control.

Part 114 - Adding properties to composite custom controls
Part 115 - Solving the problems of asp.net composite custom calendar control
Part 116 - Adding custom events to asp.net composite custom control
In this video we will discuss about assigning an image to the Composite Custom calendar control in visual studio tool box. Please watch Parts 112 to 116 from the asp.net video tutorial before proceeding with this video.
To associate an image to the composite custom calendar control use ToolboxBitmap attribute. This attribute is present in System.Drawing namespace. There are 2 ways we can use this attribute.
Using ToolboxBitmap attribute to associate, the image of an existing control: In this example, we are assigning the image of the asp.net calendar control to the composite custom calendar control. Please notice the usage of ToolboxBitmap attribute with "typeof" keyword.
[System.Drawing.ToolboxBitmap(typeof(Calendar))]
[ToolboxData("<{0}:CustomCalendar runat=server></{0}:CustomCalendar>")]
public class CustomCalendar : CompositeControl
{
TextBox textBox;
ImageButton imageButton;
Calendar calendar;
// Rest of the code.....
}
Rebuild the CustomControls project. Re-add the CustomCalendar control to visual studio tool box and notice that the asp.net calendar control icon is also used for the CustomCalendar control.

Using ToolboxBitmap attribute to associate a custom image: Create an image measuring 16X16 pixels in dimensions. I have used Microsoft paint to come up with the custom image that you can see below.
Save this image to "C:\Images" folder or in a folder of your choice. I have given the name of "CustomCalendarIcon.bmp" to the image.
Finally use the ToolboxBitmap attribute and specify the path to the image.
[System.Drawing.ToolboxBitmap(@"C:\Images\CustomCalendarIcon.bmp")]
[ToolboxData("<{0}:CustomCalendar runat=server></{0}:CustomCalendar>")]
public class CustomCalendar : CompositeControl
{
TextBox textBox;
ImageButton imageButton;
Calendar calendar;
// Rest of the code.....
}
Rebuild the CustomControls project. Re-add the CustomCalendar control to visual studio tool box and notice that the custom image "CustomCalendarIcon.bmp" is used for the CustomCalendar control.

Difference between
user controls and custom controls - Part 118
Suggested Videos
Part 115 - Solving the problems of asp.net composite custom calendar control
Part 116 - Adding custom events to asp.net composite custom control
Part 117 - Assigning an image to the composite custom control in visual studio tool box
Custom controls are compiled into their own assembly(.dll) where as user controls are not. User controls are compiled into the web application project's assembly that contain them.
Custom controls can be added to toolbox where as user controls cannot be added.
User controls are easier to create as they are similar to creating web pages. Custom controls are relatively complex, as there is no designer, and every thing has to be done in code.
A separate copy of user control is required in each application you want to use, where as a single copy of custom control can be used in multiple projects.
Please Note: When you drag and drop, a custom control, from the tool box onto a web form designer, the following 2 things can happen
1. If the custom controls assembly is not installed in GAC, then custom controls assembly is copied into the "BIN" folder of the application. So, in this case, if you need to use the custom control in multiple applications, then a copy of the custom control's assembly, will be made into the "BIN" folder of every application.
2. If the custom controls assembly is installed in GAC, then custom controls assembly is directly referenced from the GAC. So, in this case, a single copy of custom control can be used in multiple projects.
To learn about installing assemblies into GAC, please watch the following parts from Dot Net Basics Video Tutorial
Part 3 - Strong Naming an Assembly
Part 4 - What is GAC? How and when to install an assembly into GAC
Part 115 - Solving the problems of asp.net composite custom calendar control
Part 116 - Adding custom events to asp.net composite custom control
Part 117 - Assigning an image to the composite custom control in visual studio tool box
Custom controls are compiled into their own assembly(.dll) where as user controls are not. User controls are compiled into the web application project's assembly that contain them.
Custom controls can be added to toolbox where as user controls cannot be added.
User controls are easier to create as they are similar to creating web pages. Custom controls are relatively complex, as there is no designer, and every thing has to be done in code.
A separate copy of user control is required in each application you want to use, where as a single copy of custom control can be used in multiple projects.
Please Note: When you drag and drop, a custom control, from the tool box onto a web form designer, the following 2 things can happen
1. If the custom controls assembly is not installed in GAC, then custom controls assembly is copied into the "BIN" folder of the application. So, in this case, if you need to use the custom control in multiple applications, then a copy of the custom control's assembly, will be made into the "BIN" folder of every application.
2. If the custom controls assembly is installed in GAC, then custom controls assembly is directly referenced from the GAC. So, in this case, a single copy of custom control can be used in multiple projects.
To learn about installing assemblies into GAC, please watch the following parts from Dot Net Basics Video Tutorial
Part 3 - Strong Naming an Assembly
Part 4 - What is GAC? How and when to install an assembly into GAC
Caching in asp.net -
Part 119
Suggested Videos
Part 116 - Adding custom events to asp.net composite custom control
Part 117 - Assigning an image to the composite custom control in visual studio tool box
Part 118 - Difference between user controls and custom controls
Caching improves the performance and scalability of an application. Caching is the technique of storing frequently used data/pages in memory. Let us practically understand caching, with an example.
Create tblproducts table in sql server
Create Table tblProducts
(
[Id] int identity primary key,
[Name] nvarchar(50),
[Description] nvarchar(250)
)
Populate tblProducts with sample data
Insert into tblProducts values ('Laptops', 'Dell Laptops')
Insert into tblProducts values ('iPhone', 'iPhone 4S')
Insert into tblProducts values ('LCD TV', 'Samsung LCD TV')
Insert into tblProducts values ('Desktop', 'HP Desktop Computer')
Create "spGetProducts" stored procedure. In this procedure we are using WAITFOR DELAY, to block the execution of the stored procedure for 5 seconds. In real time, we may have large tables, where the query processing can take some time before the data is returned. Table "tblProducts" is a very small table, with only 4 rows. So the stored procedure "spGetProducts" would execute in a fraction of second. Just to simulate artifical query processing time of 5 seconds, we are using WAITFOR DELAY.
Create Procedure spGetProducts
As
Begin
Waitfor Delay '00:00:05'
Select Id, Name, Description
from tblProducts
End
Click here for SQL Server video tutorial that can help you, if you are new to sql server and need help creating tables, stored procedures and understanding sql server concepts.
Now, let us invoke the stored procedure in an asp.net web application, and display the "Products" data in a gridview control. Drag and drop a "gridview" control onto the web form. Copy and paste the following code in the code-behind file Page_Load() event.
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProducts", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet DS = new DataSet();
da.Fill(DS);
GridView1.DataSource = DS;
GridView1.DataBind();
Also make sure you have the following "using" declarations
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
We discussed about retrieving data from database in ado.net tutorial. Click here to access ado.net tutorial.
At this point, if you run the application, the page takes about 5 seconds to load. This is because, when you request the webform, the web server has to process the web form events, execute the stored procedure, create objects, generate HTML and send that HTML to the client broswer.
Now let us cache the webform. To cache a webform, use the @OutputCache page directive. The @OutputCache directive has 2 mandatory attributes
Duration - Specifies the time in seconds for which the webform should be cached
VaryByParam - Cache multiple responses of a single webform. For now set the value to "None". We will discuss about "VaryByParam" in a later video.
Webform with the following "OutputCache" directive is cached for 30 seconds.
<%@ OutputCache Duration="30" VaryByParam="None" %>
When any user requests this Web form for the first time, the web server will process the web form events, execute the stored procedure, create objects, generate HTML and send that HTML to the client browser, and retains a copy of the response in memory for the next 30 seconds. Any subsequent requests during that time receive the cached response.
After the cache duration has expired, the next request for the Web form, has to process the web form events, execute the stored procedure, create objects, generate HTML, which is then cached for another 30 seconds. So this web form is processed by the server, once every 30 second, at the most.
Part 116 - Adding custom events to asp.net composite custom control
Part 117 - Assigning an image to the composite custom control in visual studio tool box
Part 118 - Difference between user controls and custom controls
Caching improves the performance and scalability of an application. Caching is the technique of storing frequently used data/pages in memory. Let us practically understand caching, with an example.
Create tblproducts table in sql server
Create Table tblProducts
(
[Id] int identity primary key,
[Name] nvarchar(50),
[Description] nvarchar(250)
)
Populate tblProducts with sample data
Insert into tblProducts values ('Laptops', 'Dell Laptops')
Insert into tblProducts values ('iPhone', 'iPhone 4S')
Insert into tblProducts values ('LCD TV', 'Samsung LCD TV')
Insert into tblProducts values ('Desktop', 'HP Desktop Computer')
Create "spGetProducts" stored procedure. In this procedure we are using WAITFOR DELAY, to block the execution of the stored procedure for 5 seconds. In real time, we may have large tables, where the query processing can take some time before the data is returned. Table "tblProducts" is a very small table, with only 4 rows. So the stored procedure "spGetProducts" would execute in a fraction of second. Just to simulate artifical query processing time of 5 seconds, we are using WAITFOR DELAY.
Create Procedure spGetProducts
As
Begin
Waitfor Delay '00:00:05'
Select Id, Name, Description
from tblProducts
End
Click here for SQL Server video tutorial that can help you, if you are new to sql server and need help creating tables, stored procedures and understanding sql server concepts.
Now, let us invoke the stored procedure in an asp.net web application, and display the "Products" data in a gridview control. Drag and drop a "gridview" control onto the web form. Copy and paste the following code in the code-behind file Page_Load() event.
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProducts", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet DS = new DataSet();
da.Fill(DS);
GridView1.DataSource = DS;
GridView1.DataBind();
Also make sure you have the following "using" declarations
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
We discussed about retrieving data from database in ado.net tutorial. Click here to access ado.net tutorial.
At this point, if you run the application, the page takes about 5 seconds to load. This is because, when you request the webform, the web server has to process the web form events, execute the stored procedure, create objects, generate HTML and send that HTML to the client broswer.
Now let us cache the webform. To cache a webform, use the @OutputCache page directive. The @OutputCache directive has 2 mandatory attributes
Duration - Specifies the time in seconds for which the webform should be cached
VaryByParam - Cache multiple responses of a single webform. For now set the value to "None". We will discuss about "VaryByParam" in a later video.
Webform with the following "OutputCache" directive is cached for 30 seconds.
<%@ OutputCache Duration="30" VaryByParam="None" %>
When any user requests this Web form for the first time, the web server will process the web form events, execute the stored procedure, create objects, generate HTML and send that HTML to the client browser, and retains a copy of the response in memory for the next 30 seconds. Any subsequent requests during that time receive the cached response.
After the cache duration has expired, the next request for the Web form, has to process the web form events, execute the stored procedure, create objects, generate HTML, which is then cached for another 30 seconds. So this web form is processed by the server, once every 30 second, at the most.

Suggested Videos
Part 117 - Assigning an image to the composite custom control in visual studio tool box
Part 118 - Difference between user controls and custom controls
Part 119 - Caching in ASP.NET
In this video we will discuss about, caching multiple responses for a single webform. Please watch Part -119 from ASP.NET video tutorial, before proceeding with this video.
First create a stored procedure to get products from "tblProducts" table by product name. This procedure returns "ALL Products", if "All" is supplied as the product name, else, only the product whose name matches with the parameter "@ProductName" is returned.
Create Procedure spGetProductByName
@ProductName nvarchar(50)
as
Begin
if(@ProductName = 'All')
Begin
Select Id, Name, Description
from tblProducts
End
Else
Begin
Select Id, Name, Description
from tblProducts
where Name = @ProductName
End
End
WebForm1.aspx HTML:
<div style="font-family:Arial">
Select Product:
<asp:DropDownList ID="DropDownList1" AutoPostBack="true" runat="server"
onselectedindexchanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Text="All" Value="All"></asp:ListItem>
<asp:ListItem Text="Laptops" Value="Laptops"></asp:ListItem>
<asp:ListItem Text="iPhone" Value="iPhone"></asp:ListItem>
<asp:ListItem Text="LCD TV" Value="LCD TV"></asp:ListItem>
<asp:ListItem Text="Desktop" Value="Desktop"></asp:ListItem>
</asp:DropDownList>
<br />
<br />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<br />
<br />
Server Time:
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<br />
Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</div>
WebForm1.aspx.cs Code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetProductByName("All");
}
Label1.Text = DateTime.Now.ToString();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
GetProductByName(DropDownList1.SelectedValue);
}
private void GetProductByName(string ProductName)
{
string CS = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProductByName", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter paramProductName = new SqlParameter();
paramProductName.ParameterName = "@ProductName";
paramProductName.Value = ProductName;
da.SelectCommand.Parameters.Add(paramProductName);
DataSet DS = new DataSet();
da.Fill(DS);
GridView1.DataSource = DS;
GridView1.DataBind();
}
Include "@OutputCache" attribute with the followig settings. Notice that, since "VaryByParam" is set to "None", only one response of "WebForm1" is cached.
<%@ OutputCache Duration="60" VaryByParam="None"%>
Now change the "@OutputCache" attribute as shown below.
<%@ OutputCache Duration="60" VaryByParam="DropDownList1"%>
Since "VaryByParam" is set to "DropDownList1", up to 5 different responses will be cached for this Web form. One for each possible selection from DropDownList1 control
Part 117 - Assigning an image to the composite custom control in visual studio tool box
Part 118 - Difference between user controls and custom controls
Part 119 - Caching in ASP.NET
In this video we will discuss about, caching multiple responses for a single webform. Please watch Part -119 from ASP.NET video tutorial, before proceeding with this video.
First create a stored procedure to get products from "tblProducts" table by product name. This procedure returns "ALL Products", if "All" is supplied as the product name, else, only the product whose name matches with the parameter "@ProductName" is returned.
Create Procedure spGetProductByName
@ProductName nvarchar(50)
as
Begin
if(@ProductName = 'All')
Begin
Select Id, Name, Description
from tblProducts
End
Else
Begin
Select Id, Name, Description
from tblProducts
where Name = @ProductName
End
End
WebForm1.aspx HTML:
<div style="font-family:Arial">
Select Product:
<asp:DropDownList ID="DropDownList1" AutoPostBack="true" runat="server"
onselectedindexchanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Text="All" Value="All"></asp:ListItem>
<asp:ListItem Text="Laptops" Value="Laptops"></asp:ListItem>
<asp:ListItem Text="iPhone" Value="iPhone"></asp:ListItem>
<asp:ListItem Text="LCD TV" Value="LCD TV"></asp:ListItem>
<asp:ListItem Text="Desktop" Value="Desktop"></asp:ListItem>
</asp:DropDownList>
<br />
<br />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<br />
<br />
Server Time:
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<br />
Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</div>
WebForm1.aspx.cs Code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetProductByName("All");
}
Label1.Text = DateTime.Now.ToString();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
GetProductByName(DropDownList1.SelectedValue);
}
private void GetProductByName(string ProductName)
{
string CS = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProductByName", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter paramProductName = new SqlParameter();
paramProductName.ParameterName = "@ProductName";
paramProductName.Value = ProductName;
da.SelectCommand.Parameters.Add(paramProductName);
DataSet DS = new DataSet();
da.Fill(DS);
GridView1.DataSource = DS;
GridView1.DataBind();
}
Include "@OutputCache" attribute with the followig settings. Notice that, since "VaryByParam" is set to "None", only one response of "WebForm1" is cached.
<%@ OutputCache Duration="60" VaryByParam="None"%>
Now change the "@OutputCache" attribute as shown below.
<%@ OutputCache Duration="60" VaryByParam="DropDownList1"%>
Since "VaryByParam" is set to "DropDownList1", up to 5 different responses will be cached for this Web form. One for each possible selection from DropDownList1 control
Controlling asp.net
caching in code - Part 121
Suggested Videos
Part 118 - Difference between user controls and custom controls
Part 119 - Caching in ASP.NET
Part 120 - Caching multiple responses for a single webform
The basics of caching are discussed in Part 119, and caching multiple responses for a single webform are discussed in Part 120. In both of these videos, we discussed about controlling caching within the Webform HTML using the OutputCache directive. In this video, we will discuss about controlling caching in code.
"Cache" property of the "Response" object, can be used to control caching in code. "Response.Cache" property returns the "HttpCachePolicy" object, which can be used in code just like the "OutputCache" directive is used in webform's HTML.
Copy and paste the following HTML on the webform.
<div style="font-family: Arial">
Server Time :
<asp:Label ID="Label1" runat="server" Font-Bold="true" ></asp:Label>
<br /><br />
Client Time:
<b>
<script type="text/javascript">
document.write(Date());
</script>
</b>
</div>
Copy and paste the following code in the code-behind file
1. SetExpires() method, is used to set the duration for which we want to cachs the webform. This is similar to the "Duration" attribute of the "OutputCache" directive.
2. Response.Cache.VaryByParams["None"] = true. This is similar to setting VaryByParam="None" for the "OutputCache" directive.
3. To control the location where items are cached, we can use "Location" attribute of the "OutputCache" directive, and SetCacheability() method in code.
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "This page is cached by the server @ " + DateTime.Now.ToString();
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.VaryByParams["None"] = true;
Response.Cache.SetCacheability(HttpCacheability.Server);
}
Equivalent OutputCache settings
<%@ OutputCache Duration="60" VaryByParam="None" Location="Server" %>
Part 118 - Difference between user controls and custom controls
Part 119 - Caching in ASP.NET
Part 120 - Caching multiple responses for a single webform
The basics of caching are discussed in Part 119, and caching multiple responses for a single webform are discussed in Part 120. In both of these videos, we discussed about controlling caching within the Webform HTML using the OutputCache directive. In this video, we will discuss about controlling caching in code.
"Cache" property of the "Response" object, can be used to control caching in code. "Response.Cache" property returns the "HttpCachePolicy" object, which can be used in code just like the "OutputCache" directive is used in webform's HTML.
Copy and paste the following HTML on the webform.
<div style="font-family: Arial">
Server Time :
<asp:Label ID="Label1" runat="server" Font-Bold="true" ></asp:Label>
<br /><br />
Client Time:
<b>
<script type="text/javascript">
document.write(Date());
</script>
</b>
</div>
Copy and paste the following code in the code-behind file
1. SetExpires() method, is used to set the duration for which we want to cachs the webform. This is similar to the "Duration" attribute of the "OutputCache" directive.
2. Response.Cache.VaryByParams["None"] = true. This is similar to setting VaryByParam="None" for the "OutputCache" directive.
3. To control the location where items are cached, we can use "Location" attribute of the "OutputCache" directive, and SetCacheability() method in code.
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "This page is cached by the server @ " + DateTime.Now.ToString();
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.VaryByParams["None"] = true;
Response.Cache.SetCacheability(HttpCacheability.Server);
}
Equivalent OutputCache settings
<%@ OutputCache Duration="60" VaryByParam="None" Location="Server" %>
Suggested Videos
Part 119 - Caching in ASP.NET
Part 120 - Caching multiple responses for a single webform
Part 121 - Controlling asp.net caching in code
In this video we will discuss about fragment caching. We discussed the basics of caching in Parts 119, 120, and 121. Please watch Parts 119, 120, and 121 before proceeding with this video.
Caching parts of webform is called as partial caching or fragment caching. In a web application development, there might be scenarios where most parts of the web page changes, but only a specific section of the page is static. Let's say that specific section also takes a long time to load. This is an ideal scenario, where fragment caching can be used.
We will be using tblProducts table to understand fragment caching. Please use the script below to create and populate table tblProducts
Create Table tblProducts
(
Id int primary key,
Name nvarchar(50),
ProductDescription nvarchar(100)
)
Insert into tblProducts Values (1, 'Laptop', 'Dell Latitude Laptops')
Insert into tblProducts Values (2, 'iPhone', 'Apple iPhone 4S')
Insert into tblProducts Values (3, 'Desktop', 'Dell high performance desktops')
Insert into tblProducts Values (4, 'Server', 'HP Servers')
Script to create stored procedure that gets all the products. To introduce artificial query processing time, we are using "waitfor delay".
Create Procedure spGetProducts
as
Begin
Waitfor Delay '00:00:05'
Select * from tblProducts
End
Steps to fragment cache a webform
1. Encapsulate that sepcific sections of the page that does not constantly change into a user control.
2. Use the OutputCache directive on the user control to specify the cache settings.
3. Drag and drop the user control on the webform.
Step 1: Encapsulate specific sections of the page that does not constantly change into a user control
Create an asp.net web application project. Add a user control to the project, with name "UCProductsControl.ascx". Copy and paste the following HTML in the ascx page of the user control.
<table style="border: 1px solid black">
<tr>
<td style="background-color: Gray; font-size:12pt">
Products User Control
</td>
</tr>
<tr>
<td>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</td>
</tr>
<tr>
<td>
<b>User Control Server Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</b>
</td>
</tr>
<tr>
<td>
<b>User Control Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</b>
</td>
</tr>
</table>
Copy and paste the following code in the code-behind file of the usercontrol
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProducts", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet DS = new DataSet();
da.Fill(DS);
GridView1.DataSource = DS;
GridView1.DataBind();
}
Please make sure to include the following using declarations as well
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
Step 2: Use the OutputCache directive on the user control to specify the cache settings
<%@ OutputCache Duration="60" VaryByParam="None" %>
Step 3: Drag and drop the user control on the webform
Copy and paste the following HTML on the webform.
<div style="font-family: Arial">
<table style="border: 1px solid black">
<tr>
<td>
Page content that changes
</td>
</tr>
<tr>
<td>
<b>Page Server Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</b>
</td>
</tr>
<tr>
<td>
<b>Page Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</b>
</td>
</tr>
<tr>
<td>
<br /><br />
<uc1:UCProductsControl ID="UCProductsControl1" runat="server" />
</td>
</tr>
</table>
</div>
Copy and paste the following code in the code-behind file of the webform.
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
Notice that, when you run the web application, the user control is cached. The server time of the user control is not changed on refreshing the page but the other times on the user control and page changes. This proves that, the user control is cached, but not the rest of the webform. Fragment caching is that easy.
"Shared" attribute of the "OutputCache" directive:
"Shared" attribute can be used with "OutputCache" directive, to cache a single response from a user control for use on multiple Web forms. By default, ASP.NET caches a separate response for each Web form that uses a cached user control. Let us understand this with an example.
Add another webform with name WebForm2.aspx to the asp.net web application. Copy and paste the relevant HTML and code from WebForm1.aspx onto WebForm2.aspx.
Run the application and navigate to WebForm1.aspx. It takes around 5 seconds to load. Now navigate to WebForm2.aspx, and notice that WebForm2.aspx also takes 5 minutes. Since by default, ASP.NET caches a separate response for each Web form that uses a cached user control, both WebForm1.aspx and WebForm2.aspx, are taking 5 seconds.
Now, let's set the Shared="true" for "OutputCache" directive on "UCProductsControl" user control. This should cache a single response from the user control for use on WebForm1.aspx and WebForm2.aspx.
<%@ OutputCache Duration="60" VaryByParam="None" Shared="true" %>
Run the application and navigate to WebForm1.aspx. It takes around 5 seconds to load. Now navigate to WebForm2.aspx, and notice that WebForm2.aspx loads instantly. Also notice that, the server time of the user control is same on both the webforms. This proves that both WebForm1.aspx and WebForm2.aspx are using the single cached response of the user control.
Part 119 - Caching in ASP.NET
Part 120 - Caching multiple responses for a single webform
Part 121 - Controlling asp.net caching in code
In this video we will discuss about fragment caching. We discussed the basics of caching in Parts 119, 120, and 121. Please watch Parts 119, 120, and 121 before proceeding with this video.
Caching parts of webform is called as partial caching or fragment caching. In a web application development, there might be scenarios where most parts of the web page changes, but only a specific section of the page is static. Let's say that specific section also takes a long time to load. This is an ideal scenario, where fragment caching can be used.
We will be using tblProducts table to understand fragment caching. Please use the script below to create and populate table tblProducts
Create Table tblProducts
(
Id int primary key,
Name nvarchar(50),
ProductDescription nvarchar(100)
)
Insert into tblProducts Values (1, 'Laptop', 'Dell Latitude Laptops')
Insert into tblProducts Values (2, 'iPhone', 'Apple iPhone 4S')
Insert into tblProducts Values (3, 'Desktop', 'Dell high performance desktops')
Insert into tblProducts Values (4, 'Server', 'HP Servers')
Script to create stored procedure that gets all the products. To introduce artificial query processing time, we are using "waitfor delay".
Create Procedure spGetProducts
as
Begin
Waitfor Delay '00:00:05'
Select * from tblProducts
End
Steps to fragment cache a webform
1. Encapsulate that sepcific sections of the page that does not constantly change into a user control.
2. Use the OutputCache directive on the user control to specify the cache settings.
3. Drag and drop the user control on the webform.
Step 1: Encapsulate specific sections of the page that does not constantly change into a user control
Create an asp.net web application project. Add a user control to the project, with name "UCProductsControl.ascx". Copy and paste the following HTML in the ascx page of the user control.
<table style="border: 1px solid black">
<tr>
<td style="background-color: Gray; font-size:12pt">
Products User Control
</td>
</tr>
<tr>
<td>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</td>
</tr>
<tr>
<td>
<b>User Control Server Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</b>
</td>
</tr>
<tr>
<td>
<b>User Control Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</b>
</td>
</tr>
</table>
Copy and paste the following code in the code-behind file of the usercontrol
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProducts", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet DS = new DataSet();
da.Fill(DS);
GridView1.DataSource = DS;
GridView1.DataBind();
}
Please make sure to include the following using declarations as well
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
Step 2: Use the OutputCache directive on the user control to specify the cache settings
<%@ OutputCache Duration="60" VaryByParam="None" %>
Step 3: Drag and drop the user control on the webform
Copy and paste the following HTML on the webform.
<div style="font-family: Arial">
<table style="border: 1px solid black">
<tr>
<td>
Page content that changes
</td>
</tr>
<tr>
<td>
<b>Page Server Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</b>
</td>
</tr>
<tr>
<td>
<b>Page Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</b>
</td>
</tr>
<tr>
<td>
<br /><br />
<uc1:UCProductsControl ID="UCProductsControl1" runat="server" />
</td>
</tr>
</table>
</div>
Copy and paste the following code in the code-behind file of the webform.
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
Notice that, when you run the web application, the user control is cached. The server time of the user control is not changed on refreshing the page but the other times on the user control and page changes. This proves that, the user control is cached, but not the rest of the webform. Fragment caching is that easy.
"Shared" attribute of the "OutputCache" directive:
"Shared" attribute can be used with "OutputCache" directive, to cache a single response from a user control for use on multiple Web forms. By default, ASP.NET caches a separate response for each Web form that uses a cached user control. Let us understand this with an example.
Add another webform with name WebForm2.aspx to the asp.net web application. Copy and paste the relevant HTML and code from WebForm1.aspx onto WebForm2.aspx.
Run the application and navigate to WebForm1.aspx. It takes around 5 seconds to load. Now navigate to WebForm2.aspx, and notice that WebForm2.aspx also takes 5 minutes. Since by default, ASP.NET caches a separate response for each Web form that uses a cached user control, both WebForm1.aspx and WebForm2.aspx, are taking 5 seconds.
Now, let's set the Shared="true" for "OutputCache" directive on "UCProductsControl" user control. This should cache a single response from the user control for use on WebForm1.aspx and WebForm2.aspx.
<%@ OutputCache Duration="60" VaryByParam="None" Shared="true" %>
Run the application and navigate to WebForm1.aspx. It takes around 5 seconds to load. Now navigate to WebForm2.aspx, and notice that WebForm2.aspx loads instantly. Also notice that, the server time of the user control is same on both the webforms. This proves that both WebForm1.aspx and WebForm2.aspx are using the single cached response of the user control.
Suggested Videos
Part 120 - Caching multiple responses for a single webform
Part 121 - Controlling caching in code
Part 122 - Fragment caching
In this video, we will discuss about, how webforms are cached based on GET and POST requests. One of my youtube subscribers asked this question, related to Part 120 - Caching mulitple responses for a single web form. Please watch Part 120, from the asp.net video tutorial before proceeding with this video.
We will be using the same example from Part 120 of the asp.net video tutorial, to understand web form caching based on GET and POST requests.
Question asked by the youtube subscriber
When we have set VaryByParam="None", and accessed WebForm1.aspx, the form displayed "All" products as expected. In "Select Product" dropdownlist "All" is selected. Now when I change the selection in the dropdownlist to "iPhone", WebForm1.aspx gets posted back to the server, the form is re-processed. At this point only "iPhone" product is displayed in the gridivew control, and in the dropdownlist "iPhone" is selected.
First Question: Why was the GET request for the webform not cached for "All" products selection in the dropdownlist?
Answer: Actually, the GET request for "All" products selection in the dropdownlist is cached. To retrieve the cached response of the GET request, click any where in the URL address bar in the browser, and press ENTER key. This sends another GET request to the server, which should to return the cached response of the GET request.
Second Question: Why am I not getting the cached response of the GET request when I change the selection in the dropdownlist to "All"?
Answer: This is because, when the selection in the dropdownlist is changed to "All", a POSTBACK request is sent to the server. Since, for the POSTBACK request there is already a cached version of the webform, we get that version.
I think, when we set VaryByParam="None", a separate response is cached for GET and POST requests.
Part 120 - Caching multiple responses for a single webform
Part 121 - Controlling caching in code
Part 122 - Fragment caching
In this video, we will discuss about, how webforms are cached based on GET and POST requests. One of my youtube subscribers asked this question, related to Part 120 - Caching mulitple responses for a single web form. Please watch Part 120, from the asp.net video tutorial before proceeding with this video.
We will be using the same example from Part 120 of the asp.net video tutorial, to understand web form caching based on GET and POST requests.
Question asked by the youtube subscriber
When we have set VaryByParam="None", and accessed WebForm1.aspx, the form displayed "All" products as expected. In "Select Product" dropdownlist "All" is selected. Now when I change the selection in the dropdownlist to "iPhone", WebForm1.aspx gets posted back to the server, the form is re-processed. At this point only "iPhone" product is displayed in the gridivew control, and in the dropdownlist "iPhone" is selected.
First Question: Why was the GET request for the webform not cached for "All" products selection in the dropdownlist?
Answer: Actually, the GET request for "All" products selection in the dropdownlist is cached. To retrieve the cached response of the GET request, click any where in the URL address bar in the browser, and press ENTER key. This sends another GET request to the server, which should to return the cached response of the GET request.
Second Question: Why am I not getting the cached response of the GET request when I change the selection in the dropdownlist to "All"?
Answer: This is because, when the selection in the dropdownlist is changed to "All", a POSTBACK request is sent to the server. Since, for the POSTBACK request there is already a cached version of the webform, we get that version.
I think, when we set VaryByParam="None", a separate response is cached for GET and POST requests.
Caching multiple
versions of user control using VaryByControl - Part 124
Suggested Videos
Part 121 - Controlling caching in code
Part 122 - Fragment caching
Part 123 - Web form caching based on GET and POST requests
In Part 122 of the asp.net video tutorial, we discussed about fragment caching. Please watch Part 122 before proceeding with this video. In this video we will discuss about, caching multiple versions of user control using "VaryByControl" attribute of the "OutputCache" directive.
We will be using "tblProducts" table for this demo. If you need the script to create and populate this table, please refer to Part 122, by clicking here.
Stored procedure to get products by "Name"
Create Procedure spGetProductByName
@ProductName nvarchar(50)
as
Begin
if(@ProductName = 'All')
Begin
Select Id, Name, Description
from tblProducts
End
Else
Begin
Select Id, Name, Description
from tblProducts
where Name = @ProductName
End
End
Add a user control to the project, with name = "UCProductsControl.ascx". Copy and paste the following HTML in the usercontrol.
<table style="border: 1px solid black">
<tr>
<td style="background-color: Gray; font-size: 12pt">
Products User Control
</td>
</tr>
<tr>
<td>
Select Product:
<asp:DropDownList ID="DropDownList1" AutoPostBack="true" runat="server" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Text="All" Value="All"></asp:ListItem>
<asp:ListItem Text="Laptops" Value="Laptops"></asp:ListItem>
<asp:ListItem Text="iPhone" Value="iPhone"></asp:ListItem>
<asp:ListItem Text="LCD TV" Value="LCD TV"></asp:ListItem>
<asp:ListItem Text="Desktop" Value="Desktop"></asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</td>
</tr>
<tr>
<td>
<b>User Control Server Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</b>
</td>
</tr>
<tr>
<td>
<b>User Control Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</b>
</td>
</tr>
</table>
Copy and paste the following code in UCProductsControl.ascx.cs
public partial class UCProductsControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetProductByName("DropDownList1");
}
Label1.Text = DateTime.Now.ToString();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
GetProductByName(DropDownList1.SelectedValue);
}
private void GetProductByName(string ProductName)
{
string CS = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProductByName", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter paramProductName = new SqlParameter();
paramProductName.ParameterName = "@ProductName";
paramProductName.Value = ProductName;
da.SelectCommand.Parameters.Add(paramProductName);
DataSet DS = new DataSet();
da.Fill(DS);
GridView1.DataSource = DS;
GridView1.DataBind();
}
}
Caching multiple responses of a user control declaratively, using "VaryByControl" attribute of the "OutputCache" directive
To cache multiple response of the user control, include "OutputCache" in the aspx of the UCProductsControl.ascx. VaryByControl="DropDownList1", indicates that a separate response must be cached for each varying value in DropDownList1.
<%@ OutputCache Duration="60" VaryByControl="DropDownList1" %>
Caching multiple responses of a user control programatically, using "VaryByControls" property of the PartialCachingAttribute
We can also achieve the same thing, by specifying "PartialCachingAttribute" on the UCProductsControl class as shown below.
[PartialCaching(60, VaryByControls = "DropDownList1")]
public partial class UCProductsControl : System.Web.UI.UserControl
{
//...Rest of the UCProductsControl code
}
Please run the application and test. Notice that, as the product selections change in the dropdownlist, for each different selection a response from the user control is cached for 60 seconds. The difference between "User Control Server Time" and "User Control Client Time" proves this. Since, we don't have "Caching" set on the WebForm1.aspx, "Page Server Time" and "Page Client Time" stays the same always.
In our next video, we will discuss about when and how to use "VaryByParams" to cache multiple versions of a user control.
Part 121 - Controlling caching in code
Part 122 - Fragment caching
Part 123 - Web form caching based on GET and POST requests
In Part 122 of the asp.net video tutorial, we discussed about fragment caching. Please watch Part 122 before proceeding with this video. In this video we will discuss about, caching multiple versions of user control using "VaryByControl" attribute of the "OutputCache" directive.
We will be using "tblProducts" table for this demo. If you need the script to create and populate this table, please refer to Part 122, by clicking here.
Stored procedure to get products by "Name"
Create Procedure spGetProductByName
@ProductName nvarchar(50)
as
Begin
if(@ProductName = 'All')
Begin
Select Id, Name, Description
from tblProducts
End
Else
Begin
Select Id, Name, Description
from tblProducts
where Name = @ProductName
End
End
Add a user control to the project, with name = "UCProductsControl.ascx". Copy and paste the following HTML in the usercontrol.
<table style="border: 1px solid black">
<tr>
<td style="background-color: Gray; font-size: 12pt">
Products User Control
</td>
</tr>
<tr>
<td>
Select Product:
<asp:DropDownList ID="DropDownList1" AutoPostBack="true" runat="server" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Text="All" Value="All"></asp:ListItem>
<asp:ListItem Text="Laptops" Value="Laptops"></asp:ListItem>
<asp:ListItem Text="iPhone" Value="iPhone"></asp:ListItem>
<asp:ListItem Text="LCD TV" Value="LCD TV"></asp:ListItem>
<asp:ListItem Text="Desktop" Value="Desktop"></asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</td>
</tr>
<tr>
<td>
<b>User Control Server Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</b>
</td>
</tr>
<tr>
<td>
<b>User Control Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</b>
</td>
</tr>
</table>
Copy and paste the following code in UCProductsControl.ascx.cs
public partial class UCProductsControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetProductByName("DropDownList1");
}
Label1.Text = DateTime.Now.ToString();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
GetProductByName(DropDownList1.SelectedValue);
}
private void GetProductByName(string ProductName)
{
string CS = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProductByName", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter paramProductName = new SqlParameter();
paramProductName.ParameterName = "@ProductName";
paramProductName.Value = ProductName;
da.SelectCommand.Parameters.Add(paramProductName);
DataSet DS = new DataSet();
da.Fill(DS);
GridView1.DataSource = DS;
GridView1.DataBind();
}
}
Caching multiple responses of a user control declaratively, using "VaryByControl" attribute of the "OutputCache" directive
To cache multiple response of the user control, include "OutputCache" in the aspx of the UCProductsControl.ascx. VaryByControl="DropDownList1", indicates that a separate response must be cached for each varying value in DropDownList1.
<%@ OutputCache Duration="60" VaryByControl="DropDownList1" %>
Caching multiple responses of a user control programatically, using "VaryByControls" property of the PartialCachingAttribute
We can also achieve the same thing, by specifying "PartialCachingAttribute" on the UCProductsControl class as shown below.
[PartialCaching(60, VaryByControls = "DropDownList1")]
public partial class UCProductsControl : System.Web.UI.UserControl
{
//...Rest of the UCProductsControl code
}
Please run the application and test. Notice that, as the product selections change in the dropdownlist, for each different selection a response from the user control is cached for 60 seconds. The difference between "User Control Server Time" and "User Control Client Time" proves this. Since, we don't have "Caching" set on the WebForm1.aspx, "Page Server Time" and "Page Client Time" stays the same always.
In our next video, we will discuss about when and how to use "VaryByParams" to cache multiple versions of a user control.
Caching multiple
versions of user control using VaryByParam - Part 125
Suggested Videos
Part 122 - Fragment caching
Part 123 - Web form caching based on GET and POST requests
Part 124 - Caching multiple versions of user control using VaryByControl
In Part 124 of the asp.net video tutorial, we discussed about caching multiple versions of user control using VaryByControl attribute of the "OutputCache" directive. Please watch Part 124 before proceeding with this video.
In this video we will discuss about, caching multiple versions of user control using "VaryByParams" attribute of the "OutputCache" directive.
We will be using the same user control "UCProductsControl.ascx" from Part 124, for this demo. If you need the code associated with the user control, please refer to Part 124, by clicking here.
When should we use VaryByParam over VaryByControl and vice versa?
OR
What is the difference between VaryByParam and VaryByControl?
If you want to cache multiple responses of a user control, based on a query string or a form "POST" parameter, then use VaryByParam. On the other hand, if you want to cache multiple responses of a user control, based on a control value then use "VaryByControl".
First let us modify "UCProductsControl.ascx" user control, to load products into the gridview control, using a query string parameter. This means we can remove the "DropDownList1" control from "UCProductsControl.ascx" file. The HTML is shown below.
<table style="border: 1px solid black">
<tr>
<td style="background-color: Gray; font-size: 12pt">
Products User Control
</td>
</tr>
<tr>
<td>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</td>
</tr>
<tr>
<td>
<b>User Control Server Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</b>
</td>
</tr>
<tr>
<td>
<b>User Control Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</b>
</td>
</tr>
</table>
Make the following changes to the code-behind file of the user control
1. In Page_Load() event, remove "!IsPostBack" condition
2. Since, we want to load products using query string parameter, remove the reference to "DropDownList1" and use Request.QueryString["ProductName"]
protected void Page_Load(object sender, EventArgs e)
{
GetProductByName(Request.QueryString["ProductName"]);
Label1.Text = DateTime.Now.ToString();
}
DropDownList1_SelectedIndexChanged() method can be completely removed. The private method GetProductByName() will not change in any way.
Caching multiple responses of a user control declaratively, using "VaryByParam" attribute of the "OutputCache" directive
To cache multiple responses of the user control, include "OutputCache" directive in the aspx of the UCProductsControl.ascx. Set VaryByParam="ProductName", which indicates that a separate response must be cached for each varying value of "ProductName" query string.
<%@ OutputCache Duration="60" VaryByParam="ProductName" %>
Caching multiple responses of a user control programatically, using "VaryByParams" property of the PartialCachingAttribute
We can also achieve the same thing, by specifying "PartialCachingAttribute" on the UCProductsControl class as shown below.
[PartialCaching(60, VaryByParams = "ProductName")]
public partial class UCProductsControl : System.Web.UI.UserControl
{
//...Rest of the UCProductsControl code
}
Please run the application and test. Notice that, as the "ProductName" query string value changes, for each different value, a response from the user control is cached for 60 seconds. The difference between "User Control Server Time" and "User Control Client Time" proves this. Since, we don't have "Caching" set on the WebForm1.aspx, "Page Server Time" and "Page Client Time" stays the same always
Part 122 - Fragment caching
Part 123 - Web form caching based on GET and POST requests
Part 124 - Caching multiple versions of user control using VaryByControl
In Part 124 of the asp.net video tutorial, we discussed about caching multiple versions of user control using VaryByControl attribute of the "OutputCache" directive. Please watch Part 124 before proceeding with this video.
In this video we will discuss about, caching multiple versions of user control using "VaryByParams" attribute of the "OutputCache" directive.
We will be using the same user control "UCProductsControl.ascx" from Part 124, for this demo. If you need the code associated with the user control, please refer to Part 124, by clicking here.
When should we use VaryByParam over VaryByControl and vice versa?
OR
What is the difference between VaryByParam and VaryByControl?
If you want to cache multiple responses of a user control, based on a query string or a form "POST" parameter, then use VaryByParam. On the other hand, if you want to cache multiple responses of a user control, based on a control value then use "VaryByControl".
First let us modify "UCProductsControl.ascx" user control, to load products into the gridview control, using a query string parameter. This means we can remove the "DropDownList1" control from "UCProductsControl.ascx" file. The HTML is shown below.
<table style="border: 1px solid black">
<tr>
<td style="background-color: Gray; font-size: 12pt">
Products User Control
</td>
</tr>
<tr>
<td>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</td>
</tr>
<tr>
<td>
<b>User Control Server Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</b>
</td>
</tr>
<tr>
<td>
<b>User Control Client Time:
<script type="text/javascript">
document.write(Date());
</script>
</b>
</td>
</tr>
</table>
Make the following changes to the code-behind file of the user control
1. In Page_Load() event, remove "!IsPostBack" condition
2. Since, we want to load products using query string parameter, remove the reference to "DropDownList1" and use Request.QueryString["ProductName"]
protected void Page_Load(object sender, EventArgs e)
{
GetProductByName(Request.QueryString["ProductName"]);
Label1.Text = DateTime.Now.ToString();
}
DropDownList1_SelectedIndexChanged() method can be completely removed. The private method GetProductByName() will not change in any way.
Caching multiple responses of a user control declaratively, using "VaryByParam" attribute of the "OutputCache" directive
To cache multiple responses of the user control, include "OutputCache" directive in the aspx of the UCProductsControl.ascx. Set VaryByParam="ProductName", which indicates that a separate response must be cached for each varying value of "ProductName" query string.
<%@ OutputCache Duration="60" VaryByParam="ProductName" %>
Caching multiple responses of a user control programatically, using "VaryByParams" property of the PartialCachingAttribute
We can also achieve the same thing, by specifying "PartialCachingAttribute" on the UCProductsControl class as shown below.
[PartialCaching(60, VaryByParams = "ProductName")]
public partial class UCProductsControl : System.Web.UI.UserControl
{
//...Rest of the UCProductsControl code
}
Please run the application and test. Notice that, as the "ProductName" query string value changes, for each different value, a response from the user control is cached for 60 seconds. The difference between "User Control Server Time" and "User Control Client Time" proves this. Since, we don't have "Caching" set on the WebForm1.aspx, "Page Server Time" and "Page Client Time" stays the same always
Caching application
data in asp.net - Part 126
Suggested Videos
Part 123 - Web form caching based on GET and POST requests
Part 124 - Caching multiple versions of user control using VaryByControl
Part 125 - Caching multiple versions of user control using VaryByParam
In parts 119 to 125 of the asp.net video tutorial, we discussed about
1. Caching webforms
2. Caching multiple responses of webforms
3. Fragment caching using user controls
4. Caching multiple versions of usercontrols
Please watch these videos, from the asp.net video tutorial by clicking here, before proceeding.
In this video we will discuss about caching application data. It is possible to store application data in the web server memory, using the CACHE object, so that the data can be retrieved faster. For example, let us say, we have a stored procedure that takes 5 seconds to execute and return data. We can cache the data returned by this stored procedure with in an asp.net web application using the CACHE object, so that, next time when we try to access the data, we can get it from the cache, rather than reprocessing the stored procedure again.
We will be using "tblProducts" table for this demo. If you need the script to create and populate this table, please refer to Part 122
The following stored procedure takes 5 seconds to execute and return data. We are using WAITFOR DELAY, to introduce artificial query processing time of 5 seconds.
CREATE Procedure spGetProducts
as
Begin
Waitfor Delay '00:00:05'
Select * from tblProducts
End
Create an asp.net web application, copy and paste the following HTML in WebForm1.aspx.
<div style="font-family:Arial">
<asp:Button ID="btnGetProducts" runat="server" Text="Get Products Data"
onclick="btnGetProducts_Click" />
<br /><br />
<asp:GridView ID="gvProducts" runat="server">
</asp:GridView>
<br />
<asp:Label ID="lblMessage" Font-Bold="true" runat="server"></asp:Label>
</div>
Copy and paste the following code in WebForm1.aspx.cs. The code is well documented and is self explanatory.
protected void btnGetProducts_Click(object sender, EventArgs e)
{
DateTime dtStartDateTime = DateTime.Now;
System.Text.StringBuilder sbMessage = new System.Text.StringBuilder();
// Check if the data is already cached
if (Cache["ProductsData"] != null)
{
// If data is cached, retrieve data from Cache using the key "ProductsData"
DataSet ds = (DataSet)Cache["ProductsData"];
// Set the dataset as the datasource
gvProducts.DataSource = ds;
gvProducts.DataBind();
// Retrieve the total rows count
sbMessage.Append(ds.Tables[0].Rows.Count.ToString() + " rows retrieved from cache.");
}
// If the data is not cached
else
{
// Get the data from the database
DataSet ds = GetProductsData();
// Cache the dataset using the key "ProductsData"
Cache["ProductsData"] = ds;
// Set the dataset as the datasource
gvProducts.DataSource = ds;
gvProducts.DataBind();
sbMessage.Append(ds.Tables[0].Rows.Count.ToString() + " rows retrieved from database.");
}
DateTime dtEndDateTime = DateTime.Now;
sbMessage.Append((dtEndDateTime - dtStartDateTime).Seconds.ToString() + " Seconds Load Time");
lblMessage.Text = sbMessage.ToString();
}
private DataSet GetProductsData()
{
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProducts", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet dsProducts = new DataSet();
da.Fill(dsProducts);
return dsProducts;
}
In this video, we discussed about storing application data in cache, using direct assignment. That is using a key and assiging value to it, as shown below.
Cache["ProductsData"] = ds
Part 123 - Web form caching based on GET and POST requests
Part 124 - Caching multiple versions of user control using VaryByControl
Part 125 - Caching multiple versions of user control using VaryByParam
In parts 119 to 125 of the asp.net video tutorial, we discussed about
1. Caching webforms
2. Caching multiple responses of webforms
3. Fragment caching using user controls
4. Caching multiple versions of usercontrols
Please watch these videos, from the asp.net video tutorial by clicking here, before proceeding.
In this video we will discuss about caching application data. It is possible to store application data in the web server memory, using the CACHE object, so that the data can be retrieved faster. For example, let us say, we have a stored procedure that takes 5 seconds to execute and return data. We can cache the data returned by this stored procedure with in an asp.net web application using the CACHE object, so that, next time when we try to access the data, we can get it from the cache, rather than reprocessing the stored procedure again.
We will be using "tblProducts" table for this demo. If you need the script to create and populate this table, please refer to Part 122
The following stored procedure takes 5 seconds to execute and return data. We are using WAITFOR DELAY, to introduce artificial query processing time of 5 seconds.
CREATE Procedure spGetProducts
as
Begin
Waitfor Delay '00:00:05'
Select * from tblProducts
End
Create an asp.net web application, copy and paste the following HTML in WebForm1.aspx.
<div style="font-family:Arial">
<asp:Button ID="btnGetProducts" runat="server" Text="Get Products Data"
onclick="btnGetProducts_Click" />
<br /><br />
<asp:GridView ID="gvProducts" runat="server">
</asp:GridView>
<br />
<asp:Label ID="lblMessage" Font-Bold="true" runat="server"></asp:Label>
</div>
Copy and paste the following code in WebForm1.aspx.cs. The code is well documented and is self explanatory.
protected void btnGetProducts_Click(object sender, EventArgs e)
{
DateTime dtStartDateTime = DateTime.Now;
System.Text.StringBuilder sbMessage = new System.Text.StringBuilder();
// Check if the data is already cached
if (Cache["ProductsData"] != null)
{
// If data is cached, retrieve data from Cache using the key "ProductsData"
DataSet ds = (DataSet)Cache["ProductsData"];
// Set the dataset as the datasource
gvProducts.DataSource = ds;
gvProducts.DataBind();
// Retrieve the total rows count
sbMessage.Append(ds.Tables[0].Rows.Count.ToString() + " rows retrieved from cache.");
}
// If the data is not cached
else
{
// Get the data from the database
DataSet ds = GetProductsData();
// Cache the dataset using the key "ProductsData"
Cache["ProductsData"] = ds;
// Set the dataset as the datasource
gvProducts.DataSource = ds;
gvProducts.DataBind();
sbMessage.Append(ds.Tables[0].Rows.Count.ToString() + " rows retrieved from database.");
}
DateTime dtEndDateTime = DateTime.Now;
sbMessage.Append((dtEndDateTime - dtStartDateTime).Seconds.ToString() + " Seconds Load Time");
lblMessage.Text = sbMessage.ToString();
}
private DataSet GetProductsData()
{
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProducts", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet dsProducts = new DataSet();
da.Fill(dsProducts);
return dsProducts;
}
In this video, we discussed about storing application data in cache, using direct assignment. That is using a key and assiging value to it, as shown below.
Cache["ProductsData"] = ds
Different ways to
cache application data in asp.net - Part 127
Suggested Videos
Part 124 - Caching multiple versions of user control using VaryByControl
Part 125 - Caching multiple versions of user control using VaryByParam
Part 126 - Caching application data in asp.net
In Part 126, of the asp.net video tutorial we discussed about, "Caching application data" using direct assignment as shown below. Please watch Part 126, from the asp.net video tutorial by clicking here, before proceeding.
Cache["Cache_Key"] = Data_To_Cache
In this video we will discuss about
1. Different ways to cache application data
2. Removing an item from cache
3. Similarities and difference between cache and application state
Apart from caching data, using assignment, there are 2 other ways to cache application data
1. Using "Cache" object's Insert() method
2. Using "Cache" object's Add() method
Caching application data, using "Cache" object's Insert() method:
Cache object's, Insert() method has got 5 overloaded versions. Depending on application requirement, we can choose the overloaded version that best suits our needs. The simplest overloaded version, takes 2 parameters.
1. The Cache Key and
2. The data that we want to cache
In Part 126, we cached products dataset, using assignment as shown below
Cache["ProductsData"] = ds;
The same thing can be achieved, using cache object's "Insert()" method, as shown below.
Cache.Insert("ProductsData", ds);
We will discuss about other overloaded versions of "Insert()" method in a later video session.
Caching application data, using "Cache" object's Add() method:
Adding application data, to the cache object, using "Add()" method is similar to "Insert()" method. As "Insert()" method has got several overloaded versions, some of the parameters are optional. Where as, "Add()" method does not have any overloads, and hence, all parameters must be specified.
Cache.Add("ProductsData", ds, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null);
We will discuss about "absolute expiration", "sliding expiration", and CacheItemPriority in a later video session.
Be cautious when dealing with cache keys: Assigning a value to a cache key, that is already being used will silently overwrite the existing value, without any warnings. For example
The value stored in "MyKey" is "Value1"
Cache["MyKey"] = "Value 1";
The following line will silently overwrite "MyKey" value to "Value 2"
Cache["MyKey"] = "Value 2";
To Remove an item from cache explicitly, use Remove() method. The following line would remove the cache item with key "MyKey"
Cache.Remove("MyKey");
Please Note: An item may be removed automatically, from cache, when any of the following conditions are true
The cached item has expired.
The cache is full.
There is a cache dependency, and the item, that the cache object is dependent on has changed.
In a way, Cache object is similar to Application state. The objects that we store in application state variables are available anywhere within a Web application. Objects stored in cache are also available anywhere within a Web application. But the difference is that, items stored in cache can expire, where as items in application state will never expire.
Part 124 - Caching multiple versions of user control using VaryByControl
Part 125 - Caching multiple versions of user control using VaryByParam
Part 126 - Caching application data in asp.net
In Part 126, of the asp.net video tutorial we discussed about, "Caching application data" using direct assignment as shown below. Please watch Part 126, from the asp.net video tutorial by clicking here, before proceeding.
Cache["Cache_Key"] = Data_To_Cache
In this video we will discuss about
1. Different ways to cache application data
2. Removing an item from cache
3. Similarities and difference between cache and application state
Apart from caching data, using assignment, there are 2 other ways to cache application data
1. Using "Cache" object's Insert() method
2. Using "Cache" object's Add() method
Caching application data, using "Cache" object's Insert() method:
Cache object's, Insert() method has got 5 overloaded versions. Depending on application requirement, we can choose the overloaded version that best suits our needs. The simplest overloaded version, takes 2 parameters.
1. The Cache Key and
2. The data that we want to cache
In Part 126, we cached products dataset, using assignment as shown below
Cache["ProductsData"] = ds;
The same thing can be achieved, using cache object's "Insert()" method, as shown below.
Cache.Insert("ProductsData", ds);
We will discuss about other overloaded versions of "Insert()" method in a later video session.
Caching application data, using "Cache" object's Add() method:
Adding application data, to the cache object, using "Add()" method is similar to "Insert()" method. As "Insert()" method has got several overloaded versions, some of the parameters are optional. Where as, "Add()" method does not have any overloads, and hence, all parameters must be specified.
Cache.Add("ProductsData", ds, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null);
We will discuss about "absolute expiration", "sliding expiration", and CacheItemPriority in a later video session.
Be cautious when dealing with cache keys: Assigning a value to a cache key, that is already being used will silently overwrite the existing value, without any warnings. For example
The value stored in "MyKey" is "Value1"
Cache["MyKey"] = "Value 1";
The following line will silently overwrite "MyKey" value to "Value 2"
Cache["MyKey"] = "Value 2";
To Remove an item from cache explicitly, use Remove() method. The following line would remove the cache item with key "MyKey"
Cache.Remove("MyKey");
Please Note: An item may be removed automatically, from cache, when any of the following conditions are true
The cached item has expired.
The cache is full.
There is a cache dependency, and the item, that the cache object is dependent on has changed.
In a way, Cache object is similar to Application state. The objects that we store in application state variables are available anywhere within a Web application. Objects stored in cache are also available anywhere within a Web application. But the difference is that, items stored in cache can expire, where as items in application state will never expire.
Suggested Videos
Part 125 - Caching multiple versions of user control using VaryByParam
Part 126 - Caching application data
Part 127 - Different ways to cache application data
In this video we will discuss about AbsoluteExpiration, SlidingExpiration, and CacheItemPriority parameters of the Insert() and Add() methods of cache object.
When you cache an item using the Insert() or Add() method, you can also speicfy, how long you want the item to be cached. There are 2 ways to do this.
AbsoluteExpiration: A DateTime object that specifies when the data should be removed from the cache. When you specify "AbsoluteExpiration", the cache item will expire at that time, irrespective of whether the cached item is accessed or not.
For example, the following line will cache dataset, ds, for 10 seconds, irrespective of whether the dataset, is accessed or not within those 10 seconds, after it is cached. Since we are using absolute expiration, we specified Cache.NoSlidingExpiration for "SlidingExpiration" parameter of the Insert() method.
Cache.Insert("ProductsData", ds, null, DateTime.Now.AddSeconds(10), System.Web.Caching.Cache.NoSlidingExpiration);
SlidingExpiration: A TimeSpan object that identifies how long the data should remain in the cache after the data was last accessed.
For example, the following line will cache dataset, ds, for 10 seconds. If the dataset is accessed from the cache with in the specified 10 seconds, then, from that point, the dataset will remain in cache for the next 10 seconds. Since we are using sliding expiration, we specified Cache.NoAbsoluteExpiration for "AbsoluteExpiration" parameter of the Insert() method.
Cache.Insert("ProductsData", ds, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(10));
What happens if you specify both, AbsoluteExpiration and SlidingExpiration when caching application data?
You get a run time exception stating 'absoluteExpiration must be DateTime.MaxValue or slidingExpiration must be timeSpan.Zero'
CacheItemPriority: Sliding expiration and absolute expiration can be used to control, how long the item is cached, but please note, if the web server is running low on memory, and if it
requires memory, it may remove cached items that may not have expired. However, the order in which the items are removed is determined by the cached item's priority. Cache item's priority can be specified using CacheItemPriority enum.
CacheItemPriority enum values:
CacheItemPriority.Low
CacheItemPriority.BelowNormal
CacheItemPriority.Normal
CacheItemPriority.Default
CacheItemPriority.AboveNormal
CacheItemPriority.High
CacheItemPriority.NotRemovable
For example, let us say we have 3 items with the following priorities and they are cached.
Item 1 with CacheItemPriority.NotRemovable
Item 2 with CacheItemPriority.High
Item 3 with CacheItemPriority.AboveNormal
Now, if the server is running low on memory, it may remove the items from cache, even if they have not expired. Since, Item 3 has the least priority, it will be removed first, followed by Item 2 and then finally Item 1.
Part 125 - Caching multiple versions of user control using VaryByParam
Part 126 - Caching application data
Part 127 - Different ways to cache application data
In this video we will discuss about AbsoluteExpiration, SlidingExpiration, and CacheItemPriority parameters of the Insert() and Add() methods of cache object.
When you cache an item using the Insert() or Add() method, you can also speicfy, how long you want the item to be cached. There are 2 ways to do this.
AbsoluteExpiration: A DateTime object that specifies when the data should be removed from the cache. When you specify "AbsoluteExpiration", the cache item will expire at that time, irrespective of whether the cached item is accessed or not.
For example, the following line will cache dataset, ds, for 10 seconds, irrespective of whether the dataset, is accessed or not within those 10 seconds, after it is cached. Since we are using absolute expiration, we specified Cache.NoSlidingExpiration for "SlidingExpiration" parameter of the Insert() method.
Cache.Insert("ProductsData", ds, null, DateTime.Now.AddSeconds(10), System.Web.Caching.Cache.NoSlidingExpiration);
SlidingExpiration: A TimeSpan object that identifies how long the data should remain in the cache after the data was last accessed.
For example, the following line will cache dataset, ds, for 10 seconds. If the dataset is accessed from the cache with in the specified 10 seconds, then, from that point, the dataset will remain in cache for the next 10 seconds. Since we are using sliding expiration, we specified Cache.NoAbsoluteExpiration for "AbsoluteExpiration" parameter of the Insert() method.
Cache.Insert("ProductsData", ds, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(10));
What happens if you specify both, AbsoluteExpiration and SlidingExpiration when caching application data?
You get a run time exception stating 'absoluteExpiration must be DateTime.MaxValue or slidingExpiration must be timeSpan.Zero'
CacheItemPriority: Sliding expiration and absolute expiration can be used to control, how long the item is cached, but please note, if the web server is running low on memory, and if it
requires memory, it may remove cached items that may not have expired. However, the order in which the items are removed is determined by the cached item's priority. Cache item's priority can be specified using CacheItemPriority enum.
CacheItemPriority enum values:
CacheItemPriority.Low
CacheItemPriority.BelowNormal
CacheItemPriority.Normal
CacheItemPriority.Default
CacheItemPriority.AboveNormal
CacheItemPriority.High
CacheItemPriority.NotRemovable
For example, let us say we have 3 items with the following priorities and they are cached.
Item 1 with CacheItemPriority.NotRemovable
Item 2 with CacheItemPriority.High
Item 3 with CacheItemPriority.AboveNormal
Now, if the server is running low on memory, it may remove the items from cache, even if they have not expired. Since, Item 3 has the least priority, it will be removed first, followed by Item 2 and then finally Item 1.
Cache dependency on
files in ASP.NET - Part 129
Suggested Videos
Part 126 - Caching application data in asp.net
Part 127 - Different ways to cache application data in asp.net
Part 128 - AbsoluteExpiration, SlidingExpiration, and CacheItemPriority
In this video, we will discuss about cache dependency on files in asp.net. Let us understand this with an example. Create an asp.net web application. Add a folder with name = "Data" to your web application. Right click on the "Data" folder and add an xml file with name = "Countries.xml".
Copy and paste the following xml data into Countries.xml file.
<?xml version="1.0" encoding="utf-8" ?>
<Countries>
<Country>
<Id>101</Id>
<Name>India</Name>
<Continent>Asia</Continent>
</Country>
<Country>
<Id>102</Id>
<Name>China</Name>
<Continent>Asia</Continent>
</Country>
<Country>
<Id>103</Id>
<Name>Frnace</Name>
<Continent>Europe</Continent>
</Country>
<Country>
<Id>104</Id>
<Name>United Kingdom</Name>
<Continent>Europe</Continent>
</Country>
<Country>
<Id>105</Id>
<Name>United State of America</Name>
<Continent>North America</Continent>
</Country>
</Countries>
WebForm1.aspx HTML:
<div style="font-family: Arial">
<asp:Button ID="btnGetCountries" runat="server" Text="Get Countries"
OnClick="btnGetCountries_Click" />
<br />
<br />
<asp:GridView ID="gvCountries" runat="server">
</asp:GridView>
<br />
<asp:Label ID="lblMessage" Font-Bold="true" runat="server"></asp:Label>
</div>
The following code reads xml data from "Countries.xml" file into dataset which is then cached. Notice, that we are using "cache" object's "Insert()" method to cache the DataSet. Since we are passing "null" as the argument for "CacheDependency" parameter of the "Insert()" method, when the data in "Countries.xml" file changes, the data in the cache is unaffected.
protected void btnGetCountries_Click(object sender, EventArgs e)
{
// Check if the data is already cached
if (Cache["CountriesData"] != null)
{
// If data is cached, retrieve data from Cache
DataSet ds = (DataSet)Cache["CountriesData"];
// Set the dataset as the datasource
gvCountries.DataSource = ds;
gvCountries.DataBind();
// Retrieve the total rows count
lblMessage.Text = ds.Tables[0].Rows.Count.ToString() + " rows retrieved from cache.";
}
// If the data is not cached
else
{
// Get data from xml file
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/Data/Countries.xml"));
//Cache Countries and set dependency on file
Cache.Insert("CountriesData", ds, null, DateTime.Now.AddSeconds(20), System.Web.Caching.Cache.NoSlidingExpiration);
// Set the dataset as the datasource
gvCountries.DataSource = ds;
gvCountries.DataBind();
lblMessage.Text = ds.Tables[0].Rows.Count.ToString() + " rows retrieved from the file.";
}
}
When the data in Countries.xml file changes, we want the data in the cache to be removed automatically. For this to happen we need to establish a dependency on the xml file as shown below.
Cache.Insert("CountriesData", ds, new CacheDependency(Server.MapPath("~/Data/Countries.xml")), DateTime.Now.AddSeconds(20), System.Web.Caching.Cache.NoSlidingExpiration);
Now run the application. After the dataset is cached, change the xml file and click "Get Countries" button. Notice that the data is now retrieved from file directly, as the dataset is removed from cache.
Part 126 - Caching application data in asp.net
Part 127 - Different ways to cache application data in asp.net
Part 128 - AbsoluteExpiration, SlidingExpiration, and CacheItemPriority
In this video, we will discuss about cache dependency on files in asp.net. Let us understand this with an example. Create an asp.net web application. Add a folder with name = "Data" to your web application. Right click on the "Data" folder and add an xml file with name = "Countries.xml".
Copy and paste the following xml data into Countries.xml file.
<?xml version="1.0" encoding="utf-8" ?>
<Countries>
<Country>
<Id>101</Id>
<Name>India</Name>
<Continent>Asia</Continent>
</Country>
<Country>
<Id>102</Id>
<Name>China</Name>
<Continent>Asia</Continent>
</Country>
<Country>
<Id>103</Id>
<Name>Frnace</Name>
<Continent>Europe</Continent>
</Country>
<Country>
<Id>104</Id>
<Name>United Kingdom</Name>
<Continent>Europe</Continent>
</Country>
<Country>
<Id>105</Id>
<Name>United State of America</Name>
<Continent>North America</Continent>
</Country>
</Countries>
WebForm1.aspx HTML:
<div style="font-family: Arial">
<asp:Button ID="btnGetCountries" runat="server" Text="Get Countries"
OnClick="btnGetCountries_Click" />
<br />
<br />
<asp:GridView ID="gvCountries" runat="server">
</asp:GridView>
<br />
<asp:Label ID="lblMessage" Font-Bold="true" runat="server"></asp:Label>
</div>
The following code reads xml data from "Countries.xml" file into dataset which is then cached. Notice, that we are using "cache" object's "Insert()" method to cache the DataSet. Since we are passing "null" as the argument for "CacheDependency" parameter of the "Insert()" method, when the data in "Countries.xml" file changes, the data in the cache is unaffected.
protected void btnGetCountries_Click(object sender, EventArgs e)
{
// Check if the data is already cached
if (Cache["CountriesData"] != null)
{
// If data is cached, retrieve data from Cache
DataSet ds = (DataSet)Cache["CountriesData"];
// Set the dataset as the datasource
gvCountries.DataSource = ds;
gvCountries.DataBind();
// Retrieve the total rows count
lblMessage.Text = ds.Tables[0].Rows.Count.ToString() + " rows retrieved from cache.";
}
// If the data is not cached
else
{
// Get data from xml file
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/Data/Countries.xml"));
//Cache Countries and set dependency on file
Cache.Insert("CountriesData", ds, null, DateTime.Now.AddSeconds(20), System.Web.Caching.Cache.NoSlidingExpiration);
// Set the dataset as the datasource
gvCountries.DataSource = ds;
gvCountries.DataBind();
lblMessage.Text = ds.Tables[0].Rows.Count.ToString() + " rows retrieved from the file.";
}
}
When the data in Countries.xml file changes, we want the data in the cache to be removed automatically. For this to happen we need to establish a dependency on the xml file as shown below.
Cache.Insert("CountriesData", ds, new CacheDependency(Server.MapPath("~/Data/Countries.xml")), DateTime.Now.AddSeconds(20), System.Web.Caching.Cache.NoSlidingExpiration);
Now run the application. After the dataset is cached, change the xml file and click "Get Countries" button. Notice that the data is now retrieved from file directly, as the dataset is removed from cache.
Suggested Videos
Part 127 - Different ways to cache application data in asp.net
Part 128 - AbsoluteExpiration, SlidingExpiration, and CacheItemPriority
Part 129 - Cache dependency on files
In this video we will discuss about
1. When and how to use "CacheItemRemovedCallback" delegate
2. Reloading or refreshing cache automatically, when cached data has expired
Create an asp.net web application. Copy and paste the following HTML on WebForm1.aspx.
<div style="font-family: Arial">
<asp:Button ID="btnLoadCountriesAndCache" runat="server" Text="Load Countries & Cache"
OnClick="btnLoadCountriesAndCache_Click" />
<asp:Button ID="btnGetCountriesFromCache" runat="server" Text="Get Countries from Cache"
OnClick="btnGetCountriesFromCache_Click" />
<br />
<br />
<asp:GridView ID="gvCountries" runat="server">
</asp:GridView>
<br />
<asp:Button ID="btnRemoveCachedItem" runat="server" Text="Remove Cached Item"
OnClick="btnRemoveCachedItem_Click" />
<asp:Button ID="btnGetCacheStatus" runat="server" Text="Get Cache Status"
OnClick="btnGetCacheStatus_Click" />
<br />
<br />
<asp:Label ID="lblMessage" Font-Bold="true" runat="server"></asp:Label>
</div>
Copy and paste the following code in WebForm1.aspx.cs
protected void btnLoadCountriesAndCache_Click(object sender, EventArgs e)
{
// Load countries data from XML file into dataset
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/Data/Countries.xml"));
// Create an instance of CacheItemRemovedCallback delegate. Notice that this delegate
// points to CacheItemRemovedCallbackMethod. When cache item is removed
// for any reason
// the delegate gets invoked, which in turn will invoke the method it is pointing to.
CacheItemRemovedCallback onCacheItemRemoved =
new CacheItemRemovedCallback(CacheItemRemovedCallbackMethod);
// Cache countries dataset. Please note that we are passing the delegate instance as an
// argument for CacheItemRemovedCallback delegate parameter of the insert() method.
Cache.Insert("CountriesData", ds, new CacheDependency(Server.MapPath("~/Data/Countries.xml")), DateTime.Now.AddSeconds(60),
System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Default, onCacheItemRemoved);
// Set the dataset as the datasource for the gridview
gvCountries.DataSource = ds;
gvCountries.DataBind();
lblMessage.Text = ds.Tables[0].Rows.Count.ToString() + " rows retrieved from XML file.";
}
protected void btnGetCountriesFromCache_Click(object sender, EventArgs e)
{
// Check if countries dataset exists in cache
if (Cache["CountriesData"] != null)
{
// If countries dataset is in cache, retrieve it
DataSet ds = (DataSet)Cache["CountriesData"];
// Set the dataset as the datasource
gvCountries.DataSource = ds;
gvCountries.DataBind();
// Retrieve the total rows count
lblMessage.Text = ds.Tables[0].Rows.Count.ToString() + " rows retrieved from cache.";
}
else
{
lblMessage.Text = "Cache item with key CountriesData is not present in cache";
}
}
protected void btnRemoveCachedItem_Click(object sender, EventArgs e)
{
// Remove cached item explicitly
Cache.Remove("CountriesData");
}
// This method gets invoked automatically, whenever the cached item is removed from cache
public void CacheItemRemovedCallbackMethod(string key, object value, CacheItemRemovedReason reason)
{
// Retrieve the key and reason for removal
string dataToStore = "Cache item with key = \"" + key + "\" is no longer present. Reason = " + reason.ToString();
// Cache the message
Cache["CacheStatus"] = dataToStore;
// ADO.NET code to store the message in database
// string cs = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
// SqlConnection con = new SqlConnection(cs);
// SqlCommand cmd = new SqlCommand("insert into tblAuditLog values('" + dataToStore + "')", con);
// con.Open();
// cmd.ExecuteNonQuery();
// con.Close();
// Reload data into cache
// DataSet ds = new DataSet();
// ds.ReadXml(Server.MapPath("~/Data/Countries.xml"));
// CacheItemRemovedCallback onCacheItemRemoved = new CacheItemRemovedCallback(CacheItemRemovedCallbackMethod);
// Cache.Insert("CountriesData", ds, new CacheDependency(Server.MapPath("~/Data/Countries.xml")), DateTime.Now.AddSeconds(60),
// System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Default, onCacheItemRemoved);
}
protected void btnGetCacheStatus_Click(object sender, EventArgs e)
{
if (Cache["CountriesData"] != null)
{
lblMessage.Text = "Cache item with key \"CountriesData\" is still present in cache";
}
else
{
if (Cache["CacheStatus"] != null)
{
lblMessage.Text = Cache["CacheStatus"].ToString();
}
}
}
Explanantion of code in btnLoadCountriesAndCache_Click() event handler:
When you click "Load Countries & Cache" button, the xml data is read from "Countries.xml" into a dataset, which is then cached. Notice that, before we cache data using the "Cache" objects "Insert()" method, we are creating an instance of CacheItemRemovedCallback delegate. To the constructor of this delegate, we are passing, the name of the function that we want to have executed automatically, when the cache item is removed from cache. An item may be removed, from cache, when any of the following conditions are true
1. The cached item has expired.
2. The cache is full.
3. There is a cache dependency, and the item, that the cache object is dependent on has changed.
4. The cache item may also be explicitly removed using Cache object's Remove() method.
The delegate object is then passed as an argument for CacheItemRemovedCallback delegate parameter of the insert() method. So, when the item, with cache key="CountriesData" is removed the delegate gets invoked, which in turn will automatically invoke, the function it is pointing to, in our case "CacheItemRemovedCallbackMethod()".
Explanantion of code in CacheItemRemovedCallbackMethod() function:
This method gets invoked automatically, whenever the cached item is removed from cache. So, this is the opportunity for us to decide what we want to do when the cached item is removed from cache. For example, in this method the following 2 lines get the key of the item that is removed from the cache and the removed reason, and stores the message in another cache object, with key="CacheStatus".
string dataToStore = "Cache item with key = \"" + key + "\" is no longer present. Reason = " + reason.ToString();
Cache["CacheStatus"] = dataToStore;
Alternatively we can also store information about the removed cache object, in a database table. The ado.net code that does this is commented.
Finally we can also reload data ino cache, from the XML file. The code to reload data into cache, is also commented.
Explanantion of code in btnGetCountriesFromCache_Click() event handler:
The code in "Get Countries from Cache" button click event handler is straight forward. We check if countries data is present in cache, and if it is, we retrieve the data from cache and display in gridview control.
Code in btnRemoveCachedItem_Click() and btnGetCacheStatus_Click() is self explanatory.
Part 127 - Different ways to cache application data in asp.net
Part 128 - AbsoluteExpiration, SlidingExpiration, and CacheItemPriority
Part 129 - Cache dependency on files
In this video we will discuss about
1. When and how to use "CacheItemRemovedCallback" delegate
2. Reloading or refreshing cache automatically, when cached data has expired
Create an asp.net web application. Copy and paste the following HTML on WebForm1.aspx.
<div style="font-family: Arial">
<asp:Button ID="btnLoadCountriesAndCache" runat="server" Text="Load Countries & Cache"
OnClick="btnLoadCountriesAndCache_Click" />
<asp:Button ID="btnGetCountriesFromCache" runat="server" Text="Get Countries from Cache"
OnClick="btnGetCountriesFromCache_Click" />
<br />
<br />
<asp:GridView ID="gvCountries" runat="server">
</asp:GridView>
<br />
<asp:Button ID="btnRemoveCachedItem" runat="server" Text="Remove Cached Item"
OnClick="btnRemoveCachedItem_Click" />
<asp:Button ID="btnGetCacheStatus" runat="server" Text="Get Cache Status"
OnClick="btnGetCacheStatus_Click" />
<br />
<br />
<asp:Label ID="lblMessage" Font-Bold="true" runat="server"></asp:Label>
</div>
Copy and paste the following code in WebForm1.aspx.cs
protected void btnLoadCountriesAndCache_Click(object sender, EventArgs e)
{
// Load countries data from XML file into dataset
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/Data/Countries.xml"));
// Create an instance of CacheItemRemovedCallback delegate. Notice that this delegate
// points to CacheItemRemovedCallbackMethod. When cache item is removed
// for any reason
// the delegate gets invoked, which in turn will invoke the method it is pointing to.
CacheItemRemovedCallback onCacheItemRemoved =
new CacheItemRemovedCallback(CacheItemRemovedCallbackMethod);
// Cache countries dataset. Please note that we are passing the delegate instance as an
// argument for CacheItemRemovedCallback delegate parameter of the insert() method.
Cache.Insert("CountriesData", ds, new CacheDependency(Server.MapPath("~/Data/Countries.xml")), DateTime.Now.AddSeconds(60),
System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Default, onCacheItemRemoved);
// Set the dataset as the datasource for the gridview
gvCountries.DataSource = ds;
gvCountries.DataBind();
lblMessage.Text = ds.Tables[0].Rows.Count.ToString() + " rows retrieved from XML file.";
}
protected void btnGetCountriesFromCache_Click(object sender, EventArgs e)
{
// Check if countries dataset exists in cache
if (Cache["CountriesData"] != null)
{
// If countries dataset is in cache, retrieve it
DataSet ds = (DataSet)Cache["CountriesData"];
// Set the dataset as the datasource
gvCountries.DataSource = ds;
gvCountries.DataBind();
// Retrieve the total rows count
lblMessage.Text = ds.Tables[0].Rows.Count.ToString() + " rows retrieved from cache.";
}
else
{
lblMessage.Text = "Cache item with key CountriesData is not present in cache";
}
}
protected void btnRemoveCachedItem_Click(object sender, EventArgs e)
{
// Remove cached item explicitly
Cache.Remove("CountriesData");
}
// This method gets invoked automatically, whenever the cached item is removed from cache
public void CacheItemRemovedCallbackMethod(string key, object value, CacheItemRemovedReason reason)
{
// Retrieve the key and reason for removal
string dataToStore = "Cache item with key = \"" + key + "\" is no longer present. Reason = " + reason.ToString();
// Cache the message
Cache["CacheStatus"] = dataToStore;
// ADO.NET code to store the message in database
// string cs = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
// SqlConnection con = new SqlConnection(cs);
// SqlCommand cmd = new SqlCommand("insert into tblAuditLog values('" + dataToStore + "')", con);
// con.Open();
// cmd.ExecuteNonQuery();
// con.Close();
// Reload data into cache
// DataSet ds = new DataSet();
// ds.ReadXml(Server.MapPath("~/Data/Countries.xml"));
// CacheItemRemovedCallback onCacheItemRemoved = new CacheItemRemovedCallback(CacheItemRemovedCallbackMethod);
// Cache.Insert("CountriesData", ds, new CacheDependency(Server.MapPath("~/Data/Countries.xml")), DateTime.Now.AddSeconds(60),
// System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Default, onCacheItemRemoved);
}
protected void btnGetCacheStatus_Click(object sender, EventArgs e)
{
if (Cache["CountriesData"] != null)
{
lblMessage.Text = "Cache item with key \"CountriesData\" is still present in cache";
}
else
{
if (Cache["CacheStatus"] != null)
{
lblMessage.Text = Cache["CacheStatus"].ToString();
}
}
}
Explanantion of code in btnLoadCountriesAndCache_Click() event handler:
When you click "Load Countries & Cache" button, the xml data is read from "Countries.xml" into a dataset, which is then cached. Notice that, before we cache data using the "Cache" objects "Insert()" method, we are creating an instance of CacheItemRemovedCallback delegate. To the constructor of this delegate, we are passing, the name of the function that we want to have executed automatically, when the cache item is removed from cache. An item may be removed, from cache, when any of the following conditions are true
1. The cached item has expired.
2. The cache is full.
3. There is a cache dependency, and the item, that the cache object is dependent on has changed.
4. The cache item may also be explicitly removed using Cache object's Remove() method.
The delegate object is then passed as an argument for CacheItemRemovedCallback delegate parameter of the insert() method. So, when the item, with cache key="CountriesData" is removed the delegate gets invoked, which in turn will automatically invoke, the function it is pointing to, in our case "CacheItemRemovedCallbackMethod()".
Explanantion of code in CacheItemRemovedCallbackMethod() function:
This method gets invoked automatically, whenever the cached item is removed from cache. So, this is the opportunity for us to decide what we want to do when the cached item is removed from cache. For example, in this method the following 2 lines get the key of the item that is removed from the cache and the removed reason, and stores the message in another cache object, with key="CacheStatus".
string dataToStore = "Cache item with key = \"" + key + "\" is no longer present. Reason = " + reason.ToString();
Cache["CacheStatus"] = dataToStore;
Alternatively we can also store information about the removed cache object, in a database table. The ado.net code that does this is commented.
Finally we can also reload data ino cache, from the XML file. The code to reload data into cache, is also commented.
Explanantion of code in btnGetCountriesFromCache_Click() event handler:
The code in "Get Countries from Cache" button click event handler is straight forward. We check if countries data is present in cache, and if it is, we retrieve the data from cache and display in gridview control.
Code in btnRemoveCachedItem_Click() and btnGetCacheStatus_Click() is self explanatory.
Cache dependency on
sql server database table - Part 131
Suggested Videos
Part 128 - AbsoluteExpiration, SlidingExpiration, and CacheItemPriority
Part 129 - Cache dependency on files
Part 130 - Refreshing cache automatically, when cached data is removed
In this video, we will discuss about removing data from cache, when the data in the table from which it has come, has changed. Let us understand cache dependency on sql server database table, with an example.
First create "tblProducts" table and populate with sample data using the script below
CREATE TABLE [tblProducts]
(
[Id] [int] PRIMARY KEY IDENTITY,
[Name] [nvarchar](50) NULL,
[Description] [nvarchar](250) NULL
)
Insert into tblProducts values ('Laptops', 'Dell Laptops')
Insert into tblProducts values ('iPhone', 'iPhone 4S')
Insert into tblProducts values ('LCD TV', 'Samsung LCD TV')
Insert into tblProducts values ('Desktop', 'HP Desktop Computer')
Create an asp.net web application project. Copy and paste the following HTML on WebForm1.aspx
<div style="font-family: Arial">
<asp:Button ID="btnGetData" runat="server" Text="Get Data"
OnClick="btnGetData_Click" />
<br />
<br />
<asp:GridView ID="gvProducts" runat="server">
</asp:GridView>
<br />
<asp:Label ID="lblStatus" runat="server" Font-Bold="true">
</asp:Label>
</div>
Copy and paste the following code in WebForm1.aspx.cs
protected void btnGetData_Click(object sender, EventArgs e)
{
// Check if the DataSet is present in cache
if (Cache["ProductsData"] != null)
{
// If data available in cache, retrieve and bind it to gridview control
gvProducts.DataSource = Cache["ProductsData"];
gvProducts.DataBind();
lblStatus.Text = "Data retrieved from cache @ " + DateTime.Now.ToString();
}
else
{
// Read connection string from web.config file
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
// Enable change notifications on the database,
// so that when the data changes the cached item will be removed
System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(CS);
// Enable change notifications on the database table,
// so that when the data changes the cached item will be removed
System.Web.Caching.SqlCacheDependencyAdmin.EnableTableForNotifications(CS, "tblProducts");
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("select * from tblProducts", con);
DataSet ds = new DataSet();
da.Fill(ds);
// Build SqlCacheDependency object using the database and table names
SqlCacheDependency sqlDependency = new SqlCacheDependency("Sample", "tblProducts");
// Pass SqlCacheDependency object, when caching data
Cache.Insert("ProductsData", ds, sqlDependency);
gvProducts.DataSource = ds;
gvProducts.DataBind();
lblStatus.Text = "Data retrieved from database @ " + DateTime.Now.ToString();
}
}
In the above code, notice that, to enable SqlCacheDependency on the database and table, we are using "EnableNotifications()" and "EnableTableForNotifications()" methods, as shown below.
System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(CS)
System.Web.Caching.SqlCacheDependencyAdmin.EnableTableForNotifications(CS, "tblProducts");
Alternatively, to enable SqlCacheDependency on the database and table, we can use a command line tool, aspnet_regsql.exe. Open visual studio command prompt and execute the following 2 commands
To enable SqlCacheDependency on the "Sample" database:
aspnet_regsql -ed -E -d Sample
To enable SqlCacheDependency on "tblProducts" table in "Sample" database:
aspnet_regsql -et -E -d Sample -t tblProducts
If you need to understand the purpose of -et, -E, -d, -t, use the help, by typing the following command
aspnet_regsql /?
Finally, in web.config specify database connection string and SqlCacheDependency.
<connectionStrings>
<add name="DBCS" connectionString="data source=.; database=Sample; integrated security=SSPI"/>
</connectionStrings>
<system.web>
<caching>
<sqlCacheDependency pollTime="2000" enabled="true">
<databases>
<add name="Sample" connectionStringName="DBCS"/>
</databases>
</sqlCacheDependency>
</caching>
</system.web>
Notice that, we have set pollTime="2000". pollTime attribute specifies the frequency, at which, asp.net is going to check the database for changes. This time is in milli-seconds. Since, we have specified 2000 milli-seconds, asp.net is going to check the database for changes every 2 seconds. The default is 500 milli-seconds.
Run the application and when we click "Get Products" button for the first time, data is loaded from database. Click again, the data should be loaded from cache. Now, execute the following UPDATE query.
Update tblProducts set Name='Laptops' where Id = 1
Now, click the button again, and notice that the data is loaded from the database, as existing data is removed from cache
Part 128 - AbsoluteExpiration, SlidingExpiration, and CacheItemPriority
Part 129 - Cache dependency on files
Part 130 - Refreshing cache automatically, when cached data is removed
In this video, we will discuss about removing data from cache, when the data in the table from which it has come, has changed. Let us understand cache dependency on sql server database table, with an example.
First create "tblProducts" table and populate with sample data using the script below
CREATE TABLE [tblProducts]
(
[Id] [int] PRIMARY KEY IDENTITY,
[Name] [nvarchar](50) NULL,
[Description] [nvarchar](250) NULL
)
Insert into tblProducts values ('Laptops', 'Dell Laptops')
Insert into tblProducts values ('iPhone', 'iPhone 4S')
Insert into tblProducts values ('LCD TV', 'Samsung LCD TV')
Insert into tblProducts values ('Desktop', 'HP Desktop Computer')
Create an asp.net web application project. Copy and paste the following HTML on WebForm1.aspx
<div style="font-family: Arial">
<asp:Button ID="btnGetData" runat="server" Text="Get Data"
OnClick="btnGetData_Click" />
<br />
<br />
<asp:GridView ID="gvProducts" runat="server">
</asp:GridView>
<br />
<asp:Label ID="lblStatus" runat="server" Font-Bold="true">
</asp:Label>
</div>
Copy and paste the following code in WebForm1.aspx.cs
protected void btnGetData_Click(object sender, EventArgs e)
{
// Check if the DataSet is present in cache
if (Cache["ProductsData"] != null)
{
// If data available in cache, retrieve and bind it to gridview control
gvProducts.DataSource = Cache["ProductsData"];
gvProducts.DataBind();
lblStatus.Text = "Data retrieved from cache @ " + DateTime.Now.ToString();
}
else
{
// Read connection string from web.config file
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
// Enable change notifications on the database,
// so that when the data changes the cached item will be removed
System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(CS);
// Enable change notifications on the database table,
// so that when the data changes the cached item will be removed
System.Web.Caching.SqlCacheDependencyAdmin.EnableTableForNotifications(CS, "tblProducts");
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("select * from tblProducts", con);
DataSet ds = new DataSet();
da.Fill(ds);
// Build SqlCacheDependency object using the database and table names
SqlCacheDependency sqlDependency = new SqlCacheDependency("Sample", "tblProducts");
// Pass SqlCacheDependency object, when caching data
Cache.Insert("ProductsData", ds, sqlDependency);
gvProducts.DataSource = ds;
gvProducts.DataBind();
lblStatus.Text = "Data retrieved from database @ " + DateTime.Now.ToString();
}
}
In the above code, notice that, to enable SqlCacheDependency on the database and table, we are using "EnableNotifications()" and "EnableTableForNotifications()" methods, as shown below.
System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(CS)
System.Web.Caching.SqlCacheDependencyAdmin.EnableTableForNotifications(CS, "tblProducts");
Alternatively, to enable SqlCacheDependency on the database and table, we can use a command line tool, aspnet_regsql.exe. Open visual studio command prompt and execute the following 2 commands
To enable SqlCacheDependency on the "Sample" database:
aspnet_regsql -ed -E -d Sample
To enable SqlCacheDependency on "tblProducts" table in "Sample" database:
aspnet_regsql -et -E -d Sample -t tblProducts
If you need to understand the purpose of -et, -E, -d, -t, use the help, by typing the following command
aspnet_regsql /?
Finally, in web.config specify database connection string and SqlCacheDependency.
<connectionStrings>
<add name="DBCS" connectionString="data source=.; database=Sample; integrated security=SSPI"/>
</connectionStrings>
<system.web>
<caching>
<sqlCacheDependency pollTime="2000" enabled="true">
<databases>
<add name="Sample" connectionStringName="DBCS"/>
</databases>
</sqlCacheDependency>
</caching>
</system.web>
Notice that, we have set pollTime="2000". pollTime attribute specifies the frequency, at which, asp.net is going to check the database for changes. This time is in milli-seconds. Since, we have specified 2000 milli-seconds, asp.net is going to check the database for changes every 2 seconds. The default is 500 milli-seconds.
Run the application and when we click "Get Products" button for the first time, data is loaded from database. Click again, the data should be loaded from cache. Now, execute the following UPDATE query.
Update tblProducts set Name='Laptops' where Id = 1
Now, click the button again, and notice that the data is loaded from the database, as existing data is removed from cache
Suggested Videos
Part 129 - Cache dependency on files
Part 130 - Refreshing cache automatically, when cached data is removed
Part 131 - Cache dependency on sql server database table
In Part 130 of asp.net video tutorial, we discussed about reloading data into cache automatically, when the xml file from which the data was initially retrieved, has changed.
In this video, we will discuss about reloading data into cache automatically when data in the underlying database table has changed. Please watch Part 131, before proceeding with this video.
To load data automatically into cache, when cached data is removed, we need to define a callback method. This callback method will be invoked when the respective item is removed from cache. So, the code to reload and re-cache data can be written in this method. The callback method signature should match, with the signature of "CacheItemRemovedCallback" delegate. The call back method is defined below.
public void CacheItemRemovedCallbackMethod(string key, object value, CacheItemRemovedReason reason)
{
string CS = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProducts", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet ds = new DataSet();
da.Fill(ds);
CacheItemRemovedCallback onCacheItemRemoved = new CacheItemRemovedCallback(CacheItemRemovedCallbackMethod);
SqlCacheDependency sqlDependency = new SqlCacheDependency("Sample", "tblProducts");
Cache.Insert("ProductsData", ds, sqlDependency, DateTime.Now.AddHours(24), Cache.NoSlidingExpiration,
CacheItemPriority.Default, onCacheItemRemoved);
}
Now, create an instance of "CacheItemRemovedCallback" delegate, and to the constructor pass the name of the callback method, that should be executed automatically when, the cached item is removed.
CacheItemRemovedCallback onCacheItemRemoved = new CacheItemRemovedCallback(CacheItemRemovedCallbackMethod);
In Part 131, to cache data, we used cache object's, Insert() method that takes 3 parameters, as shown below.
Cache.Insert("ProductsData", ds, sqlDependency);
Instead, let's use the overloaded version that takes 7 parameters and pass "onCacheItemRemoved" as an argument for "CacheItemRemovedCallback" parameter.
Cache.Insert("ProductsData", ds, sqlDependency, DateTime.Now.AddHours(24), Cache.NoSlidingExpiration,
CacheItemPriority.Default, onCacheItemRemoved);
That's it. We are done. Now, please run the application. When "Get Data" button is clicked for the first time, the data is loaded from database. Once the data is loaded into cache, we always get it from cache when we click "Get Data". Now, execute an update statement on the database table. Notice that, when we click "Get Data" button now, we still get data from cache, but notice that, the updated data is loaded.
Part 129 - Cache dependency on files
Part 130 - Refreshing cache automatically, when cached data is removed
Part 131 - Cache dependency on sql server database table
In Part 130 of asp.net video tutorial, we discussed about reloading data into cache automatically, when the xml file from which the data was initially retrieved, has changed.
In this video, we will discuss about reloading data into cache automatically when data in the underlying database table has changed. Please watch Part 131, before proceeding with this video.
To load data automatically into cache, when cached data is removed, we need to define a callback method. This callback method will be invoked when the respective item is removed from cache. So, the code to reload and re-cache data can be written in this method. The callback method signature should match, with the signature of "CacheItemRemovedCallback" delegate. The call back method is defined below.
public void CacheItemRemovedCallbackMethod(string key, object value, CacheItemRemovedReason reason)
{
string CS = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetProducts", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet ds = new DataSet();
da.Fill(ds);
CacheItemRemovedCallback onCacheItemRemoved = new CacheItemRemovedCallback(CacheItemRemovedCallbackMethod);
SqlCacheDependency sqlDependency = new SqlCacheDependency("Sample", "tblProducts");
Cache.Insert("ProductsData", ds, sqlDependency, DateTime.Now.AddHours(24), Cache.NoSlidingExpiration,
CacheItemPriority.Default, onCacheItemRemoved);
}
Now, create an instance of "CacheItemRemovedCallback" delegate, and to the constructor pass the name of the callback method, that should be executed automatically when, the cached item is removed.
CacheItemRemovedCallback onCacheItemRemoved = new CacheItemRemovedCallback(CacheItemRemovedCallbackMethod);
In Part 131, to cache data, we used cache object's, Insert() method that takes 3 parameters, as shown below.
Cache.Insert("ProductsData", ds, sqlDependency);
Instead, let's use the overloaded version that takes 7 parameters and pass "onCacheItemRemoved" as an argument for "CacheItemRemovedCallback" parameter.
Cache.Insert("ProductsData", ds, sqlDependency, DateTime.Now.AddHours(24), Cache.NoSlidingExpiration,
CacheItemPriority.Default, onCacheItemRemoved);
That's it. We are done. Now, please run the application. When "Get Data" button is clicked for the first time, the data is loaded from database. Once the data is loaded into cache, we always get it from cache when we click "Get Data". Now, execute an update statement on the database table. Notice that, when we click "Get Data" button now, we still get data from cache, but notice that, the updated data is loaded.
Suggested Videos
Part 130 - Refreshing cache automatically, when cached data is removed
Part 131 - Cache dependency on sql server database table
Part 132 - Reload data into cache automatically when data in the table changes
Let us understand the use of AutoEventWireup property with an example. Create an asp.net web application project.
A webform in asp.net raises several events in it's life cycle. The following are few of those events.
1. Page Load
2. Page Load Complete
3. Page PreRender
4. Page PreRenderComplete
Copy and paste the following code in WebForm1.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Page Load <br/>");
}
protected void Page_LoadComplete(object sender, EventArgs e)
{
Response.Write("Page LoadComplete <br/>");
}
protected void Page_PreRender(object sender, EventArgs e)
{
Response.Write("Page PreRender <br/>");
}
protected void Page_PreRenderComplete(object sender, EventArgs e)
{
Response.Write("Page PreRenderComplete <br/>");
}
Now in WebForm1.aspx, set AutoEventWireup=true
Run the application, and notice that the above event handler methods are executed as expected. We did not explicitly associate event handler methods to the events, but still the event handler methods are hooked up to their respective events. This is because we have AutoEventWireup attribute set to true.
Now, set AutoEventWireup=false
Run the application, and notice that none of the above event handler methods are executed. This is because, when "AutoEventWireup" property is set to false, the event handler methods does not get automatically associated with their respective events. We have to explicitly associate them by overriding OnInit() method as shown below. Now, copy and paste the following code in webform1.aspx.cs
protected override void OnInit(EventArgs e)
{
this.Load += new EventHandler(Page_Load);
this.LoadComplete += new EventHandler(Page_LoadComplete);
this.PreRender += new EventHandler(Page_PreRender);
this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);
}
Run the application, and notice that the above event handler methods are executed as expected.
Now, set AutoEventWireup=true
Run the application, and notice that every event handler method is executed twice. This is because,
1. Setting AutoEventWireup=true, registered the event handler method's once, and
2. Overriding OnInit() method, has registered the same event handler method again
Important points to remember:
1. When AutoEventWireup is set to true and if you want the event handlers to be wired up with their events automatically, the event handler names should follow the standarad naming convention - Page_EventName.
2. AutoEventWireup can be set in the page directive or in web.config file.
3. To set autoEventWireup in web.config, use pages element as shown below.
<configuration>
<system.web>
<pages autoEventWireup="true" />
</system.web>
</configuration>
4. If autoEventWireup, is set at both webform and web.config level, webform setting will take precedence over web.config setting.
So, AutoEventWireup is a boolean property which, when set to true, the page event handler methods are automatically wired with their respective events. If this property is set to false, then the event handler methods need to be explicitly associated with their respective events
Part 130 - Refreshing cache automatically, when cached data is removed
Part 131 - Cache dependency on sql server database table
Part 132 - Reload data into cache automatically when data in the table changes
Let us understand the use of AutoEventWireup property with an example. Create an asp.net web application project.
A webform in asp.net raises several events in it's life cycle. The following are few of those events.
1. Page Load
2. Page Load Complete
3. Page PreRender
4. Page PreRenderComplete
Copy and paste the following code in WebForm1.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Page Load <br/>");
}
protected void Page_LoadComplete(object sender, EventArgs e)
{
Response.Write("Page LoadComplete <br/>");
}
protected void Page_PreRender(object sender, EventArgs e)
{
Response.Write("Page PreRender <br/>");
}
protected void Page_PreRenderComplete(object sender, EventArgs e)
{
Response.Write("Page PreRenderComplete <br/>");
}
Now in WebForm1.aspx, set AutoEventWireup=true
Run the application, and notice that the above event handler methods are executed as expected. We did not explicitly associate event handler methods to the events, but still the event handler methods are hooked up to their respective events. This is because we have AutoEventWireup attribute set to true.
Now, set AutoEventWireup=false
Run the application, and notice that none of the above event handler methods are executed. This is because, when "AutoEventWireup" property is set to false, the event handler methods does not get automatically associated with their respective events. We have to explicitly associate them by overriding OnInit() method as shown below. Now, copy and paste the following code in webform1.aspx.cs
protected override void OnInit(EventArgs e)
{
this.Load += new EventHandler(Page_Load);
this.LoadComplete += new EventHandler(Page_LoadComplete);
this.PreRender += new EventHandler(Page_PreRender);
this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);
}
Run the application, and notice that the above event handler methods are executed as expected.
Now, set AutoEventWireup=true
Run the application, and notice that every event handler method is executed twice. This is because,
1. Setting AutoEventWireup=true, registered the event handler method's once, and
2. Overriding OnInit() method, has registered the same event handler method again
Important points to remember:
1. When AutoEventWireup is set to true and if you want the event handlers to be wired up with their events automatically, the event handler names should follow the standarad naming convention - Page_EventName.
2. AutoEventWireup can be set in the page directive or in web.config file.
3. To set autoEventWireup in web.config, use pages element as shown below.
<configuration>
<system.web>
<pages autoEventWireup="true" />
</system.web>
</configuration>
4. If autoEventWireup, is set at both webform and web.config level, webform setting will take precedence over web.config setting.
So, AutoEventWireup is a boolean property which, when set to true, the page event handler methods are automatically wired with their respective events. If this property is set to false, then the event handler methods need to be explicitly associated with their respective events
Add image slideshow to
your website using asp.net ajax and c# - Part 134
Suggested Videos
Part 131 - Cache dependency on sql server database table
Part 132 - Reload data into cache automatically when data in the table changes
Part 133 - What is AutoEventWireup in asp.net
In this video, we will discuss adding image slideshow to a website or web application.
Step 1: Create an asp.net web application project.
Step 2: In the solution explorer, right click on the project name, and add "Images" folder.
Step 3: For this demo, we will use the sample pictures that are shipped with Microsoft operating system. Copy the images that are present at the following path, and paste them into the images folder.
C:\Users\Public\Pictures\Sample Pictures
Rename the images to use numbers. Since on my machine there are 8 images, I have named them 1.jpg, 2.jpg to 8.jpg. At this point, your solution explorer should look as show below.

Step 4: Drag and drop "ScriptManager" control onto the webform. This control can be found under "AJAX Extensions" in toolbox. ScriptManager control is required on any asp.net page, where you want to take adavantage of asp.net ajax framework. We will discuss more about ScriptManager control in our upcoming asp.net ajax tutorial.
Step 5: Drag and drop "UpdatePanel" control. This control, allow us to perform partial page postbacks as opposed to a full page postback. The responsiveness of a page can be significantly increased using partial page postback, as only the data that is relevant to that UpdatePanel is sent to the server, and only the corresponding data is returned. Another benefit of partial page postbacks is that, they avoid screen flickers that are very common with full page postbacks.
All the content of the updatepanel, must be placed inside ContentTemplate element, so include <ContentTemplate> tag directly inside updatepanel. Drag and drop, the timer and image controls onto the webform, so that they are placed inside the <ContentTemplate> tag.
1. The Timer control raises a tick event. This event is raised when the specified timer interval has elapsed and the timer is enabled.
2. Timer interval is specified in milli-seconds. For example, If you want the tick event to be raised every one second, then set "Interval" property of timer control to "1000" milliseconds.
3. We will use the tick event of the timer control to change the image dynamically every one second. So, flip the webform to design mode, if it's not already in design mode. Double click on the timer control. This should generate an event handler for tick event.
4. Set the Image control height and width to 100px.
5. Finally copy and paste the following code in the code-behind file.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SetImageUrl();
}
}
private void SetImageUrl()
{
// Create an instance of Random class
Random _rand = new Random();
// Generate a random number between 1 and 8
int i = _rand.Next(1, 8);
// Set ImageUrl using the generated random number
Image1.ImageUrl = "~/Images/" + i.ToString() + ".jpg";
}
// This event is raised every one second as we have set
// the interval to 1000 milliseconds
protected void Timer1_Tick(object sender, EventArgs e)
{
SetImageUrl();
}
At the moment, the problem with this code is that, it displays a random image every one second. Let's say our requirement is such that, we want to display images in order from 1.jpg, 2.jpg to 8.jpg. Also, below the image, display the number of the image that is being displayed. We will discuss fixing this in our next video.
Part 131 - Cache dependency on sql server database table
Part 132 - Reload data into cache automatically when data in the table changes
Part 133 - What is AutoEventWireup in asp.net
In this video, we will discuss adding image slideshow to a website or web application.
Step 1: Create an asp.net web application project.
Step 2: In the solution explorer, right click on the project name, and add "Images" folder.
Step 3: For this demo, we will use the sample pictures that are shipped with Microsoft operating system. Copy the images that are present at the following path, and paste them into the images folder.
C:\Users\Public\Pictures\Sample Pictures
Rename the images to use numbers. Since on my machine there are 8 images, I have named them 1.jpg, 2.jpg to 8.jpg. At this point, your solution explorer should look as show below.

Step 4: Drag and drop "ScriptManager" control onto the webform. This control can be found under "AJAX Extensions" in toolbox. ScriptManager control is required on any asp.net page, where you want to take adavantage of asp.net ajax framework. We will discuss more about ScriptManager control in our upcoming asp.net ajax tutorial.
Step 5: Drag and drop "UpdatePanel" control. This control, allow us to perform partial page postbacks as opposed to a full page postback. The responsiveness of a page can be significantly increased using partial page postback, as only the data that is relevant to that UpdatePanel is sent to the server, and only the corresponding data is returned. Another benefit of partial page postbacks is that, they avoid screen flickers that are very common with full page postbacks.
All the content of the updatepanel, must be placed inside ContentTemplate element, so include <ContentTemplate> tag directly inside updatepanel. Drag and drop, the timer and image controls onto the webform, so that they are placed inside the <ContentTemplate> tag.
1. The Timer control raises a tick event. This event is raised when the specified timer interval has elapsed and the timer is enabled.
2. Timer interval is specified in milli-seconds. For example, If you want the tick event to be raised every one second, then set "Interval" property of timer control to "1000" milliseconds.
3. We will use the tick event of the timer control to change the image dynamically every one second. So, flip the webform to design mode, if it's not already in design mode. Double click on the timer control. This should generate an event handler for tick event.
4. Set the Image control height and width to 100px.
5. Finally copy and paste the following code in the code-behind file.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SetImageUrl();
}
}
private void SetImageUrl()
{
// Create an instance of Random class
Random _rand = new Random();
// Generate a random number between 1 and 8
int i = _rand.Next(1, 8);
// Set ImageUrl using the generated random number
Image1.ImageUrl = "~/Images/" + i.ToString() + ".jpg";
}
// This event is raised every one second as we have set
// the interval to 1000 milliseconds
protected void Timer1_Tick(object sender, EventArgs e)
{
SetImageUrl();
}
At the moment, the problem with this code is that, it displays a random image every one second. Let's say our requirement is such that, we want to display images in order from 1.jpg, 2.jpg to 8.jpg. Also, below the image, display the number of the image that is being displayed. We will discuss fixing this in our next video.
Suggested Videos
Part 132 - Reload data into cache automatically when data in the table changes
Part 133 - What is AutoEventWireup in asp.net
Part 134 - Add image slideshow to your website using asp.net ajax and c#
In Part 134, we discussed adding image slideshow to a website or a web application. the problem with slideshow is that, it displays a random image every one second. Let's say our requirement is such that, we want to display images in order from 1.jpg, 2.jpg to 8.jpg. Also, below the image, we want to display the number of the image that is being displayed. Please watch Part 134, before proceeding. We will be modifying the example, that we started in Part 134.
To achieve this,
Step 1: Include "Label1" control in the aspx page. This label control displays the image number that is being displayed.
<br /><asp:Label ID="Label1" Font-Bold="true" runat="server"></asp:Label>
Step 2: Change the code in SetImageUrl() function as shown below
private void SetImageUrl()
{
if (ViewState["ImageDisplayed"] == null)
{
Image1.ImageUrl = "~/Images/1.jpg";
ViewState["ImageDisplayed"] = 1;
Label1.Text = "Displaying Image - 1";
}
else
{
int i = (int)ViewState["ImageDisplayed"];
if (i == 8)
{
Image1.ImageUrl = "~/Images/1.jpg";
ViewState["ImageDisplayed"] = 1;
Label1.Text = "Displaying Image - 1";
}
else
{
i = i + 1;
Image1.ImageUrl = "~/Images/" + i.ToString() + ".jpg";
ViewState["ImageDisplayed"] = i;
Label1.Text = "Displaying Image - " + i.ToString();
}
}
}
At the moment, there is no mechanism in place to start or stop the slideshow. We will discuss this in our next video.
Part 132 - Reload data into cache automatically when data in the table changes
Part 133 - What is AutoEventWireup in asp.net
Part 134 - Add image slideshow to your website using asp.net ajax and c#
In Part 134, we discussed adding image slideshow to a website or a web application. the problem with slideshow is that, it displays a random image every one second. Let's say our requirement is such that, we want to display images in order from 1.jpg, 2.jpg to 8.jpg. Also, below the image, we want to display the number of the image that is being displayed. Please watch Part 134, before proceeding. We will be modifying the example, that we started in Part 134.
To achieve this,
Step 1: Include "Label1" control in the aspx page. This label control displays the image number that is being displayed.
<br /><asp:Label ID="Label1" Font-Bold="true" runat="server"></asp:Label>
Step 2: Change the code in SetImageUrl() function as shown below
private void SetImageUrl()
{
if (ViewState["ImageDisplayed"] == null)
{
Image1.ImageUrl = "~/Images/1.jpg";
ViewState["ImageDisplayed"] = 1;
Label1.Text = "Displaying Image - 1";
}
else
{
int i = (int)ViewState["ImageDisplayed"];
if (i == 8)
{
Image1.ImageUrl = "~/Images/1.jpg";
ViewState["ImageDisplayed"] = 1;
Label1.Text = "Displaying Image - 1";
}
else
{
i = i + 1;
Image1.ImageUrl = "~/Images/" + i.ToString() + ".jpg";
ViewState["ImageDisplayed"] = i;
Label1.Text = "Displaying Image - " + i.ToString();
}
}
}
At the moment, there is no mechanism in place to start or stop the slideshow. We will discuss this in our next video.
Provide capability to
start and stop image slideshow - Part 136
Suggested Videos
Part 133 - What is AutoEventWireup in asp.net
Part 134 - Add image slideshow to your website using asp.net ajax and c#
Part 135 - Display images in sequence in an image slideshow
Please watch Parts 134 & 135 before proceeding. We will be continuing with the example, that we started in Part 135. At the moment, there is no mechanism in place to start or stop the slideshow.
What we want to achieve in this video?

1. Provide a button control as shown in the image
2. If the Sildeshow has not already started, the text on the button will be "Start Slideshow"
3. Once the button is clicked, the "slideshow" starts, and then, the text on the button will be changed to "Stop Slideshow". The images should be displayed in sequence from 1 to 8. The images should be changed dynamically in sequence until "Stop Slideshow" button is clicked.
4. Once "Stop SlideShow" button is clicked, the slideshow should stop. If the user clicks "start slideshow", then the slide show sould resume from where it was left.
To achieve this
1. Drag and drop a button control on the webform.
2. Set Text= "Stop Slideshow".
3. Generate click event handler from Button1. Copy and paste the following code.
protected void Button1_Click(object sender, EventArgs e)
{
// If timer is enabled, disable timer and change
// the text on the button control accordingly
if (Timer1.Enabled)
{
Timer1.Enabled = false;
Button1.Text = "Start Slideshow";
}
// If timer is disabled, enable timer and change
// the text on the button control accordingly
else
{
Timer1.Enabled = true;
Button1.Text = "Stop Slideshow";
}
}
At the moment, there are 2 problems with this code. If we want to add a new image to the slide show,
1. We will have to modify the application code
2. The new image has to be named in a specific way. Since we already have 8 images, the next image has to be named 9.jpg.
Part 133 - What is AutoEventWireup in asp.net
Part 134 - Add image slideshow to your website using asp.net ajax and c#
Part 135 - Display images in sequence in an image slideshow
Please watch Parts 134 & 135 before proceeding. We will be continuing with the example, that we started in Part 135. At the moment, there is no mechanism in place to start or stop the slideshow.
What we want to achieve in this video?

1. Provide a button control as shown in the image
2. If the Sildeshow has not already started, the text on the button will be "Start Slideshow"
3. Once the button is clicked, the "slideshow" starts, and then, the text on the button will be changed to "Stop Slideshow". The images should be displayed in sequence from 1 to 8. The images should be changed dynamically in sequence until "Stop Slideshow" button is clicked.
4. Once "Stop SlideShow" button is clicked, the slideshow should stop. If the user clicks "start slideshow", then the slide show sould resume from where it was left.
To achieve this
1. Drag and drop a button control on the webform.
2. Set Text= "Stop Slideshow".
3. Generate click event handler from Button1. Copy and paste the following code.
protected void Button1_Click(object sender, EventArgs e)
{
// If timer is enabled, disable timer and change
// the text on the button control accordingly
if (Timer1.Enabled)
{
Timer1.Enabled = false;
Button1.Text = "Start Slideshow";
}
// If timer is disabled, enable timer and change
// the text on the button control accordingly
else
{
Timer1.Enabled = true;
Button1.Text = "Stop Slideshow";
}
}
At the moment, there are 2 problems with this code. If we want to add a new image to the slide show,
1. We will have to modify the application code
2. The new image has to be named in a specific way. Since we already have 8 images, the next image has to be named 9.jpg.

Suggested Videos
Part 134 - Add image slideshow to your website using asp.net ajax and c#
Part 135 - Display images in sequence in an image slideshow
Part 136 - Provide capability to start and stop image slideshow
There are 2 problems with the image slideshow, that we have built in Parts 134, 135, & 136. If we want to add a new image to the slide show,
1. We will have to modify the application code
2. The new image has to be named in a specific way. Since we already have 8 images, the next image has to be named 9.jpg.
There are two ways to fix the above 2 issues.
1. Using an XML file
2. Using a database table
In this video, we will discuss using an XML file and in our next video, we will discuss using a database table.
Step 1: At the moment the images in "Images" folder have the following names
1.jpg
2.jpg
3.jpg
etc...
Delete all these 8 images. Now copy the images with their original names from "C:\Users\Public\Pictures\Sample Pictures".
Step 2: Right click on the project name in solution explorer, and add "Data" folder. Add "ImageData.xml" file. Copy and paste the following XML
<?xml version="1.0" encoding="utf-8" ?>
<Images>
<image name="Chrysanthemum.jpg" order="1"></image>
<image name="Desert.jpg" order="2"></image>
<image name="Hydrangeas.jpg" order="3"></image>
<image name="Jellyfish.jpg" order="4"></image>
<image name="Koala.jpg" order="5"></image>
<image name="Lighthouse.jpg" order="6"></image>
<image name="Penguins.jpg" order="7"></image>
<image name="Tulips.jpg" order="8"></image>
</Images>
At this point your solution explorer, should be as shown below.

Deafult.aspx code:
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="ImageSlideShow._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick">
</asp:Timer>
<asp:Image ID="Image1" Height="200px" Width="200px" runat="server" />
<br />
<br />
Name: <asp:Label ID="lblImageName" runat="server"></asp:Label>
<br />
Order: <asp:Label ID="lblImageOrder" runat="server"></asp:Label>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Stop Slideshow"
onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
Default.aspx.cs code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
namespace ImageSlideShow
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadImageData();
}
}
private void LoadImageData()
{
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/Data/ImageData.xml"));
ViewState["ImageData"] = ds;
ViewState["ImageDisplayed"] = 1;
DataRow imageDataRow = ds.Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == "1");
Image1.ImageUrl = "~/Images/" + imageDataRow["name"].ToString();
lblImageName.Text = imageDataRow["name"].ToString();
lblImageOrder.Text = imageDataRow["order"].ToString();
}
protected void Timer1_Tick(object sender, EventArgs e)
{
int i = (int)ViewState["ImageDisplayed"];
i = i + 1;
ViewState["ImageDisplayed"] = i;
DataRow imageDataRow = ((DataSet)ViewState["ImageData"]).Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == i.ToString());
if (imageDataRow != null)
{
Image1.ImageUrl = "~/Images/" + imageDataRow["name"].ToString();
lblImageName.Text = imageDataRow["name"].ToString();
lblImageOrder.Text = imageDataRow["order"].ToString();
}
else
{
LoadImageData();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Timer1.Enabled)
{
Timer1.Enabled = false;
Button1.Text = "Start Slideshow";
}
else
{
Timer1.Enabled = true;
Button1.Text = "Stop Slideshow";
}
}
}
}
To add a new image to the slideshow, there are 2 simple steps
1. Add your new image to the images folder
2. Update "ImageData.xml" file
Part 134 - Add image slideshow to your website using asp.net ajax and c#
Part 135 - Display images in sequence in an image slideshow
Part 136 - Provide capability to start and stop image slideshow
There are 2 problems with the image slideshow, that we have built in Parts 134, 135, & 136. If we want to add a new image to the slide show,
1. We will have to modify the application code
2. The new image has to be named in a specific way. Since we already have 8 images, the next image has to be named 9.jpg.
There are two ways to fix the above 2 issues.
1. Using an XML file
2. Using a database table
In this video, we will discuss using an XML file and in our next video, we will discuss using a database table.
Step 1: At the moment the images in "Images" folder have the following names
1.jpg
2.jpg
3.jpg
etc...
Delete all these 8 images. Now copy the images with their original names from "C:\Users\Public\Pictures\Sample Pictures".
Step 2: Right click on the project name in solution explorer, and add "Data" folder. Add "ImageData.xml" file. Copy and paste the following XML
<?xml version="1.0" encoding="utf-8" ?>
<Images>
<image name="Chrysanthemum.jpg" order="1"></image>
<image name="Desert.jpg" order="2"></image>
<image name="Hydrangeas.jpg" order="3"></image>
<image name="Jellyfish.jpg" order="4"></image>
<image name="Koala.jpg" order="5"></image>
<image name="Lighthouse.jpg" order="6"></image>
<image name="Penguins.jpg" order="7"></image>
<image name="Tulips.jpg" order="8"></image>
</Images>
At this point your solution explorer, should be as shown below.

Deafult.aspx code:
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="ImageSlideShow._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick">
</asp:Timer>
<asp:Image ID="Image1" Height="200px" Width="200px" runat="server" />
<br />
<br />
Name: <asp:Label ID="lblImageName" runat="server"></asp:Label>
<br />
Order: <asp:Label ID="lblImageOrder" runat="server"></asp:Label>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Stop Slideshow"
onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
Default.aspx.cs code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
namespace ImageSlideShow
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadImageData();
}
}
private void LoadImageData()
{
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/Data/ImageData.xml"));
ViewState["ImageData"] = ds;
ViewState["ImageDisplayed"] = 1;
DataRow imageDataRow = ds.Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == "1");
Image1.ImageUrl = "~/Images/" + imageDataRow["name"].ToString();
lblImageName.Text = imageDataRow["name"].ToString();
lblImageOrder.Text = imageDataRow["order"].ToString();
}
protected void Timer1_Tick(object sender, EventArgs e)
{
int i = (int)ViewState["ImageDisplayed"];
i = i + 1;
ViewState["ImageDisplayed"] = i;
DataRow imageDataRow = ((DataSet)ViewState["ImageData"]).Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == i.ToString());
if (imageDataRow != null)
{
Image1.ImageUrl = "~/Images/" + imageDataRow["name"].ToString();
lblImageName.Text = imageDataRow["name"].ToString();
lblImageOrder.Text = imageDataRow["order"].ToString();
}
else
{
LoadImageData();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Timer1.Enabled)
{
Timer1.Enabled = false;
Button1.Text = "Start Slideshow";
}
else
{
Timer1.Enabled = true;
Button1.Text = "Stop Slideshow";
}
}
}
}
To add a new image to the slideshow, there are 2 simple steps
1. Add your new image to the images folder
2. Update "ImageData.xml" file
Add images to
slideshow using database table - Part 138
Suggested Videos
Part 135 - Display images in sequence in an image slideshow
Part 136 - Provide capability to start and stop image slideshow
Part 137 - Add images to slideshow using xml file
In Part 137, we discussed storing the image data in an xml file. In this video, we will be using a database table to store image data. So, we can safely delete ImageData.xml file. Please watch Part 137, before proceeding.
To store image data, create table tblImages
Create table tblImages
(
[ID] int identity primary key,
[Name] nvarchar(50),
[Order] int
)
SQL script to insert image data
Insert into tblImages values('Chrysanthemum.jpg',1)
Insert into tblImages values('Desert.jpg',2)
Insert into tblImages values('Hydrangeas.jpg',3)
Insert into tblImages values('Jellyfish.jpg',4)
Insert into tblImages values('Koala.jpg',5)
Insert into tblImages values('Lighthouse.jpg',6)
Insert into tblImages values('Penguins.jpg',7)
Insert into tblImages values('Tulips.jpg',8)
Insert into tblImages values('MyImage.jpg',9)
Stored procedure to retrieve image data
Create procedure spGetImageData
as
Begin
Select [Name], [Order] from tblImages
End
After the table is created, create a connection string in web.config.
<connectionStrings>
<add name="DBCS"
connectionString="data source=.;Integrated Security=SSPI;database=Sample"
providerName="System.Data.SqlClient" />
</connectionStrings>
We now have to write ADO.NET code to retrieve image data from the database table. The rest of the logic remains unchanged. Here's the complete code for your reference.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace ImageSlideShow
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SetImageUrl();
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
int i = (int)ViewState["ImageDisplayed"];
i = i + 1;
ViewState["ImageDisplayed"] = i;
DataRow imageDataRow = ((DataSet)ViewState["ImageData"]).Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == i.ToString());
if (imageDataRow != null)
{
Image1.ImageUrl = "~/Images/" + imageDataRow["name"].ToString();
lblImageName.Text = imageDataRow["name"].ToString();
lblImageOrder.Text = imageDataRow["order"].ToString();
}
else
{
SetImageUrl();
}
}
private void SetImageUrl()
{
DataSet ds = new DataSet();
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetImageData", con);
da.Fill(ds, "image");
ViewState["ImageData"] = ds;
ViewState["ImageDisplayed"] = 1;
DataRow imageDataRow = ds.Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == "1");
Image1.ImageUrl = "~/Images/" + imageDataRow["name"].ToString();
lblImageName.Text = imageDataRow["name"].ToString();
lblImageOrder.Text = imageDataRow["order"].ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Timer1.Enabled)
{
Timer1.Enabled = false;
Button1.Text = "Start Slideshow";
}
else
{
Timer1.Enabled = true;
Button1.Text = "Stop Slideshow";
}
}
}
}
To add a new image to the slideshow
1. Copy the image to the images folder
2. Insert the new image name and it's order into tblImages table.
Part 135 - Display images in sequence in an image slideshow
Part 136 - Provide capability to start and stop image slideshow
Part 137 - Add images to slideshow using xml file
In Part 137, we discussed storing the image data in an xml file. In this video, we will be using a database table to store image data. So, we can safely delete ImageData.xml file. Please watch Part 137, before proceeding.
To store image data, create table tblImages
Create table tblImages
(
[ID] int identity primary key,
[Name] nvarchar(50),
[Order] int
)
SQL script to insert image data
Insert into tblImages values('Chrysanthemum.jpg',1)
Insert into tblImages values('Desert.jpg',2)
Insert into tblImages values('Hydrangeas.jpg',3)
Insert into tblImages values('Jellyfish.jpg',4)
Insert into tblImages values('Koala.jpg',5)
Insert into tblImages values('Lighthouse.jpg',6)
Insert into tblImages values('Penguins.jpg',7)
Insert into tblImages values('Tulips.jpg',8)
Insert into tblImages values('MyImage.jpg',9)
Stored procedure to retrieve image data
Create procedure spGetImageData
as
Begin
Select [Name], [Order] from tblImages
End
After the table is created, create a connection string in web.config.
<connectionStrings>
<add name="DBCS"
connectionString="data source=.;Integrated Security=SSPI;database=Sample"
providerName="System.Data.SqlClient" />
</connectionStrings>
We now have to write ADO.NET code to retrieve image data from the database table. The rest of the logic remains unchanged. Here's the complete code for your reference.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace ImageSlideShow
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SetImageUrl();
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
int i = (int)ViewState["ImageDisplayed"];
i = i + 1;
ViewState["ImageDisplayed"] = i;
DataRow imageDataRow = ((DataSet)ViewState["ImageData"]).Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == i.ToString());
if (imageDataRow != null)
{
Image1.ImageUrl = "~/Images/" + imageDataRow["name"].ToString();
lblImageName.Text = imageDataRow["name"].ToString();
lblImageOrder.Text = imageDataRow["order"].ToString();
}
else
{
SetImageUrl();
}
}
private void SetImageUrl()
{
DataSet ds = new DataSet();
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter("spGetImageData", con);
da.Fill(ds, "image");
ViewState["ImageData"] = ds;
ViewState["ImageDisplayed"] = 1;
DataRow imageDataRow = ds.Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == "1");
Image1.ImageUrl = "~/Images/" + imageDataRow["name"].ToString();
lblImageName.Text = imageDataRow["name"].ToString();
lblImageOrder.Text = imageDataRow["order"].ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Timer1.Enabled)
{
Timer1.Enabled = false;
Button1.Text = "Start Slideshow";
}
else
{
Timer1.Enabled = true;
Button1.Text = "Stop Slideshow";
}
}
}
}
To add a new image to the slideshow
1. Copy the image to the images folder
2. Insert the new image name and it's order into tblImages table.
Suggested Videos
Part 136 - Provide capability to start and stop image slideshow
Part 137 - Add images to slideshow using xml file
Part 138 - Add images to slideshow using database table
In this video, we will discuss
1. Uploading files
2. Displaying the list of files that are already uploaded
3. Downloading files
The user interface to upload and download files, should be as shown below.

When the files are uploaded, they should be uploaded to a folder on the web server. In our case, we will be uploading to "Data" folder.

WebForm1.aspx code:
<div style="font-family:Arial">
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Upload"
OnClick="Button1_Click" />
<br />
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
OnRowCommand="GridView1_RowCommand" BackColor="White"
BorderColor="#CC9966" BorderStyle="None"
BorderWidth="1px" CellPadding="4">
<Columns>
<asp:TemplateField HeaderText="File" ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server"
CausesValidation="False"
CommandArgument='<%# Eval("File") %>'
CommandName="Download" Text='<%# Eval("File") %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Size" HeaderText="Size in Bytes" />
<asp:BoundField DataField="Type" HeaderText="File Type" />
</Columns>
<FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
<HeaderStyle BackColor="#990000" Font-Bold="True"
ForeColor="#FFFFCC" />
<PagerStyle BackColor="#FFFFCC" ForeColor="#330099"
HorizontalAlign="Center" />
<RowStyle BackColor="White" ForeColor="#330099" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True"
ForeColor="#663399" />
<SortedAscendingCellStyle BackColor="#FEFCEB" />
<SortedAscendingHeaderStyle BackColor="#AF0101" />
<SortedDescendingCellStyle BackColor="#F6F0C0" />
<SortedDescendingHeaderStyle BackColor="#7E0000" />
</asp:GridView>
</div>
WebForm1.aspx.cs code:
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string fileName = FileUpload1.FileName;
FileUpload1.PostedFile
.SaveAs(Server.MapPath("~/Data/") + fileName);
}
DataTable dt = new DataTable();
dt.Columns.Add("File");
dt.Columns.Add("Size");
dt.Columns.Add("Type");
foreach (string strfile in Directory.GetFiles(Server.MapPath("~/Data")))
{
FileInfo fi = new FileInfo(strfile);
dt.Rows.Add(fi.Name, fi.Length.ToString(),
GetFileTypeByExtension(fi.Extension));
}
GridView1.DataSource = dt;
GridView1.DataBind();
}
private string GetFileTypeByExtension(string fileExtension)
{
switch (fileExtension.ToLower())
{
case ".docx":
case ".doc":
return "Microsoft Word Document";
case ".xlsx":
case ".xls":
return "Microsoft Excel Document";
case ".txt":
return "Text Document";
case ".jpg":
case ".png":
return "Image";
default:
return "Unknown";
}
}
protected void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "filename="
+ e.CommandArgument);
Response.TransmitFile(Server.MapPath("~/Data/")
+ e.CommandArgument);
Response.End();
}
Please make sure to include the following using declarations in the code behind file.
using System.IO;
using System.Data;
Part 136 - Provide capability to start and stop image slideshow
Part 137 - Add images to slideshow using xml file
Part 138 - Add images to slideshow using database table
In this video, we will discuss
1. Uploading files
2. Displaying the list of files that are already uploaded
3. Downloading files
The user interface to upload and download files, should be as shown below.

When the files are uploaded, they should be uploaded to a folder on the web server. In our case, we will be uploading to "Data" folder.

WebForm1.aspx code:
<div style="font-family:Arial">
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Upload"
OnClick="Button1_Click" />
<br />
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
OnRowCommand="GridView1_RowCommand" BackColor="White"
BorderColor="#CC9966" BorderStyle="None"
BorderWidth="1px" CellPadding="4">
<Columns>
<asp:TemplateField HeaderText="File" ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server"
CausesValidation="False"
CommandArgument='<%# Eval("File") %>'
CommandName="Download" Text='<%# Eval("File") %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Size" HeaderText="Size in Bytes" />
<asp:BoundField DataField="Type" HeaderText="File Type" />
</Columns>
<FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
<HeaderStyle BackColor="#990000" Font-Bold="True"
ForeColor="#FFFFCC" />
<PagerStyle BackColor="#FFFFCC" ForeColor="#330099"
HorizontalAlign="Center" />
<RowStyle BackColor="White" ForeColor="#330099" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True"
ForeColor="#663399" />
<SortedAscendingCellStyle BackColor="#FEFCEB" />
<SortedAscendingHeaderStyle BackColor="#AF0101" />
<SortedDescendingCellStyle BackColor="#F6F0C0" />
<SortedDescendingHeaderStyle BackColor="#7E0000" />
</asp:GridView>
</div>
WebForm1.aspx.cs code:
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string fileName = FileUpload1.FileName;
FileUpload1.PostedFile
.SaveAs(Server.MapPath("~/Data/") + fileName);
}
DataTable dt = new DataTable();
dt.Columns.Add("File");
dt.Columns.Add("Size");
dt.Columns.Add("Type");
foreach (string strfile in Directory.GetFiles(Server.MapPath("~/Data")))
{
FileInfo fi = new FileInfo(strfile);
dt.Rows.Add(fi.Name, fi.Length.ToString(),
GetFileTypeByExtension(fi.Extension));
}
GridView1.DataSource = dt;
GridView1.DataBind();
}
private string GetFileTypeByExtension(string fileExtension)
{
switch (fileExtension.ToLower())
{
case ".docx":
case ".doc":
return "Microsoft Word Document";
case ".xlsx":
case ".xls":
return "Microsoft Excel Document";
case ".txt":
return "Text Document";
case ".jpg":
case ".png":
return "Image";
default:
return "Unknown";
}
}
protected void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "filename="
+ e.CommandArgument);
Response.TransmitFile(Server.MapPath("~/Data/")
+ e.CommandArgument);
Response.End();
}
Please make sure to include the following using declarations in the code behind file.
using System.IO;
using System.Data;

Suggested Videos
Part 137 - Add images to slideshow using xml file
Part 138 - Add images to slideshow using database table
Part 139 - How to upload and download files using asp.net and c#
In this video, we will discuss creating an image gallery using asp.net and c#. The images in the galley should be displayed as click-able thumbnails. Upon clicking the thumbnail, the user should be redirected to a page, where he can see the original image. Upon uploading an image, the image should be added to the gallery immediately. The output should be as shown below.

The images used in the demo can be found at the following link
http://windows.microsoft.com/en-GB/windows/wallpaper
Add "Data" folder to the project. This folder stores the uploaded images.
WebForm1.aspx
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Upload" OnClick="Button1_Click" />
<asp:Panel ID="Panel1" runat="server" Width="440px"
BorderStyle="Dashed" BorderColor="#000066">
</asp:Panel>
WebForm1.aspx.cs
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LoadImages();
}
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string fileName = FileUpload1.FileName;
FileUpload1.PostedFile.SaveAs(Server.MapPath("~/Data/") + fileName);
}
Response.Redirect("~/WebForm1.aspx");
}
private void LoadImages()
{
foreach (string strfile in Directory.GetFiles(Server.MapPath("~/Data")))
{
ImageButton imageButton = new ImageButton();
FileInfo fi = new FileInfo(strfile);
imageButton.ImageUrl = "~/Data/" + fi.Name;
imageButton.Height = Unit.Pixel(100);
imageButton.Style.Add("padding", "5px");
imageButton.Width = Unit.Pixel(100);
imageButton.Click += new ImageClickEventHandler(imageButton_Click);
Panel1.Controls.Add(imageButton);
}
}
protected void imageButton_Click(object sender, ImageClickEventArgs e)
{
Response.Redirect("WebForm2.aspx?ImageURL=" +
((ImageButton)sender).ImageUrl);
}
}
WebForm2.aspx
<asp:Button ID="Button2" Text="Back to Gallery" runat="server" onclick="Button1_Click" />
<br /><br />
<asp:Image ID="Image1" Width="800px" Height="550px" runat="server" />
<br /><br />
<asp:Button ID="Button1" Text="Back to Gallery" runat="server" onclick="Button1_Click" />
WebForm2.aspx.cs
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Image1.ImageUrl = Request.QueryString["ImageURL"];
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("WebForm1.aspx");
}
}
Part 137 - Add images to slideshow using xml file
Part 138 - Add images to slideshow using database table
Part 139 - How to upload and download files using asp.net and c#
In this video, we will discuss creating an image gallery using asp.net and c#. The images in the galley should be displayed as click-able thumbnails. Upon clicking the thumbnail, the user should be redirected to a page, where he can see the original image. Upon uploading an image, the image should be added to the gallery immediately. The output should be as shown below.

The images used in the demo can be found at the following link
http://windows.microsoft.com/en-GB/windows/wallpaper
Add "Data" folder to the project. This folder stores the uploaded images.
WebForm1.aspx
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Upload" OnClick="Button1_Click" />
<asp:Panel ID="Panel1" runat="server" Width="440px"
BorderStyle="Dashed" BorderColor="#000066">
</asp:Panel>
WebForm1.aspx.cs
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LoadImages();
}
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string fileName = FileUpload1.FileName;
FileUpload1.PostedFile.SaveAs(Server.MapPath("~/Data/") + fileName);
}
Response.Redirect("~/WebForm1.aspx");
}
private void LoadImages()
{
foreach (string strfile in Directory.GetFiles(Server.MapPath("~/Data")))
{
ImageButton imageButton = new ImageButton();
FileInfo fi = new FileInfo(strfile);
imageButton.ImageUrl = "~/Data/" + fi.Name;
imageButton.Height = Unit.Pixel(100);
imageButton.Style.Add("padding", "5px");
imageButton.Width = Unit.Pixel(100);
imageButton.Click += new ImageClickEventHandler(imageButton_Click);
Panel1.Controls.Add(imageButton);
}
}
protected void imageButton_Click(object sender, ImageClickEventArgs e)
{
Response.Redirect("WebForm2.aspx?ImageURL=" +
((ImageButton)sender).ImageUrl);
}
}
WebForm2.aspx
<asp:Button ID="Button2" Text="Back to Gallery" runat="server" onclick="Button1_Click" />
<br /><br />
<asp:Image ID="Image1" Width="800px" Height="550px" runat="server" />
<br /><br />
<asp:Button ID="Button1" Text="Back to Gallery" runat="server" onclick="Button1_Click" />
WebForm2.aspx.cs
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Image1.ImageUrl = Request.QueryString["ImageURL"];
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("WebForm1.aspx");
}
}
Part 141 - Contact us
page using asp.net and c#
Suggested Videos
Part 138 - Add images to slideshow using database table
Part 139 - How to upload and download files using asp.net and c#
Part 140 - Creating an image gallery using asp.net and c#
In this video, we will discuss designing contact us page using asp.net and c#. It's very common for web sites to contain a contact us page which allows the users of the site to contact either the administrator or the support group. A typical contact-us page is shown below.

contactus.aspx:
<div style="font-family: Arial">
<fieldset style="width: 350px">
<legend title="Contact us">Contact us</legend>
<table>
<tr>
<td>
<b>Name:</b>
</td>
<td>
<asp:TextBox
ID="txtName"
Width="200px"
runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
ForeColor="Red"
ID="RequiredFieldValidator1"
runat="server"
ControlToValidate="txtName"
ErrorMessage="Name is required"
Text="*">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
<b>Email:</b>
</td>
<td>
<asp:TextBox
ID="txtEmail"
Width="200px"
runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
Display="Dynamic"
ForeColor="Red"
ID="RequiredFieldValidator2"
runat="server"
ControlToValidate="txtEmail"
ErrorMessage="Email is required"
Text="*">
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator
Display="Dynamic"
ForeColor="Red"
ID="RegularExpressionValidator1"
runat="server"
ErrorMessage="Invalid Email"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
ControlToValidate="txtEmail"
Text="*">
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
<b>Subject:</b>
</td>
<td>
<asp:TextBox
ID="txtSubject"
Width="200px"
runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
ForeColor="Red"
ID="RequiredFieldValidator3"
runat="server"
ControlToValidate="txtSubject"
ErrorMessage="Subject is required"
Text="*">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td style="vertical-align: top">
<b>Comments:</b>
</td>
<td style="vertical-align: top">
<asp:TextBox
ID="txtComments"
Width="200px"
TextMode="MultiLine"
Rows="5"
runat="server">
</asp:TextBox>
</td>
<td style="vertical-align: top">
<asp:RequiredFieldValidator
ForeColor="Red"
ID="RequiredFieldValidator4"
runat="server"
ControlToValidate="txtComments"
ErrorMessage="Comments is required"
Text="*">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td colspan="3">
<asp:ValidationSummary
HeaderText="Please fix the following errors"
ForeColor="Red"
ID="ValidationSummary1"
runat="server" />
</td>
</tr>
<tr>
<td colspan="3">
<asp:Label
ID="lblMessage"
runat="server"
Font-Bold="true">
</asp:Label>
</td>
</tr>
<tr>
<td colspan="3">
<asp:Button
ID="Button1"
runat="server"
Text="Submit"
OnClick="Button1_Click" />
</td>
</tr>
</table>
</fieldset>
</div>
contactus.aspx.cs
public partial class contactus : System.Web.UI.Page
{
protected void Button1_Click(object sender, EventArgs e)
{
// To Do. Implementation will be discussed in Part 142
}
}
Part 138 - Add images to slideshow using database table
Part 139 - How to upload and download files using asp.net and c#
Part 140 - Creating an image gallery using asp.net and c#
In this video, we will discuss designing contact us page using asp.net and c#. It's very common for web sites to contain a contact us page which allows the users of the site to contact either the administrator or the support group. A typical contact-us page is shown below.

contactus.aspx:
<div style="font-family: Arial">
<fieldset style="width: 350px">
<legend title="Contact us">Contact us</legend>
<table>
<tr>
<td>
<b>Name:</b>
</td>
<td>
<asp:TextBox
ID="txtName"
Width="200px"
runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
ForeColor="Red"
ID="RequiredFieldValidator1"
runat="server"
ControlToValidate="txtName"
ErrorMessage="Name is required"
Text="*">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
<b>Email:</b>
</td>
<td>
<asp:TextBox
ID="txtEmail"
Width="200px"
runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
Display="Dynamic"
ForeColor="Red"
ID="RequiredFieldValidator2"
runat="server"
ControlToValidate="txtEmail"
ErrorMessage="Email is required"
Text="*">
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator
Display="Dynamic"
ForeColor="Red"
ID="RegularExpressionValidator1"
runat="server"
ErrorMessage="Invalid Email"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
ControlToValidate="txtEmail"
Text="*">
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
<b>Subject:</b>
</td>
<td>
<asp:TextBox
ID="txtSubject"
Width="200px"
runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
ForeColor="Red"
ID="RequiredFieldValidator3"
runat="server"
ControlToValidate="txtSubject"
ErrorMessage="Subject is required"
Text="*">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td style="vertical-align: top">
<b>Comments:</b>
</td>
<td style="vertical-align: top">
<asp:TextBox
ID="txtComments"
Width="200px"
TextMode="MultiLine"
Rows="5"
runat="server">
</asp:TextBox>
</td>
<td style="vertical-align: top">
<asp:RequiredFieldValidator
ForeColor="Red"
ID="RequiredFieldValidator4"
runat="server"
ControlToValidate="txtComments"
ErrorMessage="Comments is required"
Text="*">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td colspan="3">
<asp:ValidationSummary
HeaderText="Please fix the following errors"
ForeColor="Red"
ID="ValidationSummary1"
runat="server" />
</td>
</tr>
<tr>
<td colspan="3">
<asp:Label
ID="lblMessage"
runat="server"
Font-Bold="true">
</asp:Label>
</td>
</tr>
<tr>
<td colspan="3">
<asp:Button
ID="Button1"
runat="server"
Text="Submit"
OnClick="Button1_Click" />
</td>
</tr>
</table>
</fieldset>
</div>
contactus.aspx.cs
public partial class contactus : System.Web.UI.Page
{
protected void Button1_Click(object sender, EventArgs e)
{
// To Do. Implementation will be discussed in Part 142
}
}
Suggested Videos
Part 139 - How to upload and download files using asp.net and c#
Part 140 - Creating an image gallery using asp.net and c#
Part 141 - Contact us page using asp.net and c#
In Part 141, we discussed designing "contact us" page. In this video, we will implement the server side code. Once the form is submitted, an email should be sent to the support group. The email should contain all the details that are entered in the contact us form.

Please make sure to include the following 2 namespaces.
using System;
using System.Net.Mail;
contactus.aspx.cs:
protected void Button1_Click(object sender, EventArgs e)
{
try
{
if (Page.IsValid)
{
MailMessage mailMessage = new MailMessage();
mailMessage.From = new MailAddress("YourGmailID@gmail.com");
mailMessage.To.Add("AdministratorID@YourCompany.com");
mailMessage.Subject = txtSubject.Text;
mailMessage.Body = "<b>Sender Name : </b>" + txtName.Text + "<br/>"
+ "<b>Sender Email : </b>" + txtEmail.Text + "<br/>"
+ "<b>Comments : </b>" + txtComments.Text;
mailMessage.IsBodyHtml = true;
SmtpClient smtpClient = new SmtpClient("smtp.gmail.com", 587);
smtpClient.EnableSsl = true;
smtpClient.Credentials = new
System.Net.NetworkCredential("YourGmailID@gmail.com", "YourGmailPassowrd");
smtpClient.Send(mailMessage);
Label1.ForeColor = System.Drawing.Color.Blue;
Label1.Text = "Thank you for contacting us";
txtName.Enabled = false;
txtEmail.Enabled = false;
txtComments.Enabled = false;
txtSubject.Enabled = false;
Button1.Enabled = false;
}
}
catch (Exception ex)
{
// Log the exception information to
// database table or event viewer
Label1.ForeColor = System.Drawing.Color.Red;
Label1.Text = "There is an unkwon problem. Please try later";
}
}
No comments:
Post a Comment