Dynamically updating pages content of your website

SheoNarayan
Posted by in ASP.NET category on for Intermediate level | Views : 9557 red flag

If you are a webmaster or an administrator of the website, you must have came across a situation where you need to change the description or introduction of the page time to time or you need to add some extra lines or a special offers details based on the circumstances or importance of the page.


 Download source code for Dynamically updating pages content of your website

In normal case, these static texts create a lot of hassle of changing the contents of the file and uploading it on the server again and again.

Here, I am going to explain a quick and easy solution without compromising the performance of the page a lot. This solution is database driven but I am not going to hit the database every time a page is requested from the website. This is going to be a custom server control so performance is a bonus here. The good thing is that this works with dynamic urls of the website too (The url that is created using HttpHandlers) and you can use HTML tags in the description to format the text as you would have done while manually editing the page. In this article, I am using description word instead of introduction of the page.

In process of creating dynamically writing page description control, we are going to do following things.

• Create a database table named “tblPageDescription” and five Stored Procedures to manipulate data.
• Create admin pages to Insert, Update, Delete records (basic pages).
• Create Custom Server Control (PageDescription.cs).

Complete ready to use downloadable project with source code is available, your may prefer to download it from top-right side link. However, I am going to cover each step briefly.

Let’s create this control and its related things step-wise
Step – 1
Create a table into the database

Create a database table named “tblPageDescription” with fields as displayed in the picture below
AutoID – AutoEncrement
PageName – Varchar(50)
PageDescription – Varchar(500)
Active - Bit



Now create five stored procedures for inserting, updating, deleting and loading data.
spInsertData used to insert records into database

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE [dbo].[spInsertData]
(
@PageName varchar(50),
@PageDescription varchar(500),
@Active bit
)
AS
INSERT INTO tblPageDescription (PageName, PageDescription, Active) VALUES
(@PageName, @PageDescription, @Active)
RETURN



spUpdateData used to update record into database

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [dbo].[spUpdateData]
(
@AutoID int,
@PageName varchar(50),
@PageDescription varchar(500),
@Active bit
)
AS
UPDATE tblPageDescription SET PageName = @PageName, PageDescription = @PageDescription,
Active = @Active WHERE AutoID = @AutoID
RETURN



spDeleteData used to delete record from database

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE [dbo].[spDeleteData]
(
@AutoID int
)
AS
DELETE FROM tblPageDescription WHERE AutoID = @AutoID
RETURN


spGetData used to load all records from database

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE [dbo].[spGetData]

AS
SELECT * FROM tblPageDescription ORDER BY PageName
RETURN


spGetPagesDescription used to load only active records from database

CREATE PROCEDURE [dbo].spGetPagesDescription
AS
BEGIN
SELECT * FROM tblPageDescription WHERE Active = 1 ORDER BY PageName
END
GO


Step – 2
Create admin pages to manipulate description of the pages

First I am going to create a Blank solution and will add a website. I will have two pages named default.aspx (to insert records into database) and ListPage.aspx (to list and manipulate pages description records).

/admin/Default.aspx Insert records into tblPageDescription database tatble



/admin/ListPage.aspx Allow you to update, delete records from database.





Step – 3
Creating Custom Server Control

Now I am going to create few pages in my demo project so that we can test if the dynamic page description control is working fine or not. In this project I have a MasterPage.master, Default.aspx, Page1.aspx, Page2.aspx, Page3.aspx as displayed in the picture below.




So, till now our ingredients for creating, managing and testing our dynamically writing page description control is ready, now let’s create our Custom Server Control that will be placed in the master pages (If you don’t have master page, you can place this control in .aspx pages).

Add a new project (Windows Class Library) named MyControls and create a new class file named PageDescription.cs. Write following using statement at the top of the page besides existing using statement and inherit base Control class.

using System.Web.UI;
using System.Configuration;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

Sometimes based on your installation and version you may not be able to work with System.Web and related namespaces directly and while compiling it may throw error. To overcome this error, you may need to add reference of System.Web by right clicking the References of the project and selecting System.Web from the .NET Tab. Below is the code for writing Custom Server Control named PageDescription. You may exactly copy-paste this code.


using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Configuration;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

namespace TutorialsPageDesc
{
public class PageDescription : Control
{
/* PLEASE NOTE:
* In Practical scenario you should prefer to use your existing architecture to get
* the data from database, However for this demo project, I am directly using Sql objects
* and getting records from database */

// override the render method
protected override void Render(HtmlTextWriter writer)
{
string m_PageName = HttpContext.Current.Request.Url.AbsolutePath;

WritePageDescription(writer, m_PageName);
}


/// <summary>
/// write actual description from database
/// </summary>
/// <param name="writer"></param>
private void WritePageDescription(HtmlTextWriter writer, string pageName)
{
string strPageDescription = string.Empty;
strPageDescription = GetPageDescription(pageName);
// if there is some description for this page then write it otherwise leave it
if (strPageDescription.Length > 0)
{
writer.WriteFullBeginTag("div");
writer.Write(HttpContext.Current.Server.HtmlDecode(strPageDescription).Replace("\n", "<br />"));
writer.WriteEndTag("div");
}
}

/// <summary>
/// Get data from database or cache
/// </summary>
/// <returns></returns>
private string GetPageDescription(string pageName)
{

DataTable dTable = new DataTable();
string strPageDesc = string.Empty;
string strCahceName = ConfigurationSettings.AppSettings["PageDescCacheName"].ToString();

// first check the data into cache, if its there get from cache even don't initialize any object
// You are gaining performance here
if (System.Web.HttpContext.Current.Cache[strCahceName] == null)
{
string connStr = System.Configuration.ConfigurationSettings.AppSettings["ConnStr"].ToString();
SqlConnection conn = new SqlConnection(connStr);
SqlDataAdapter dAd = new SqlDataAdapter("spGetPagesDescription", conn);
DataSet dSet = new DataSet();
try
{
conn.Open();
dAd.Fill(dSet, "PagesData");
dTable = dSet.Tables[0];

// store data into cacheblnotd
System.Web.HttpContext.Current.Cache[strCahceName] = dTable;

}
catch (Exception ee)
{
// I am returning error so that I can track what error occured while getting the data, you may return nothing
strPageDesc = ee.Message;
}
finally
{
dSet.Dispose();
dAd.Dispose();
conn.Close();
conn.Dispose();
}
}
else
{
dTable = System.Web.HttpContext.Current.Cache[strCahceName] as DataTable;
}


if (dTable.Rows.Count > 0)
{
// you have all data now, filter it based on parameter
DataRow[] row = dTable.Select(" PageName = '" + pageName + "'");

if (row.Length > 0) // if there is any data for this page then set properties
{
strPageDesc = row[0]["PageDescription"].ToString();
}
}

return strPageDesc;
}


} // class
} // namespacec


Render method that overrides the Render method of the control base class and receives HtmlTextWriter as a parameter, I am getting the current requested page name using HttpContext.Current.Request.Url.AbsolutePath. This will give me only the name of the file that is being requested currently. Even if there will be any querystring with this url at the time of request, it will only give the absolute path of the page (path from your root folder of the application). This absolute path will be passed to the private method named WritePageDescription that will take care of writing descriptioin of the page. This method will again calls GetPageDescription method with pageName as the parameter to get the actual description of the page, if any.

For Simplicity reason, I have not used layered architecture to get the data, instead I am using Sql objects directly to this control and getting the data from database for the first time.

GetPageDescription method will check for the Cache of the page description data, if not found then it will connect to the database, get the data and stores into a DataTable. The same DataTable will be stored into the Cache so that in the next request application doesn’t need to hit the database for the page description records again. Once the records are stored into the Cache it will check for the no. of records into the DataTable, as there might be a chance that you have not entered or you don’t want any description for a particular page. When it ensures that there are some records into the DataTable, it filter the records based on the pageName parameter and stores into the local variable and return it to its parent WritePageDescription method. WritePageDescription method will check for the returned value and write the actual description of the page if any.

When subsequent time any page is requested from your website, application checks for the Cache records and once found, it will skip the database connecting block and get the records from the Cache and serve to the website. In this way, we are not hitting the database again and again to get the page description and saving resources and processing time.

Please note that you need to remove the Cached object at the time of inserting, updating and deleting records so that the updated page description will be immediately cached again in the next request. To remove the object from Cache, please use following code:


System.Web.HttpContext.Current.Cache.Remove(ConfigurationManager.AppSettings["PageDescCacheName"].ToString());


You may find this code in the downloaded source code.

So now you have your Custom server control ready. Just Build it and add reference to this project (MyControls) to your Website project by right clicking the Website and clicking Add Reference … as displayed in the picture – 5.




Step – 4
Registering Custom Server Control to your page


Now, it’s time to register your control to your master page and placing it as desired place so that it works for all pages of your website. If you have named the same way I did, your Register directives in the master page should look like


<%@ Register Namespace="TutorialsPageDesc" TagPrefix="MyPage" Assembly="MyControls" %>


Choose the place where you want to call this control and write following code

<MyPage:PageDescription id="Pd1" runat="server" />


Step – 5
Its time to test now


Now you are done. Go to your admin pages (in my case http://localhost/admin/default.aspx) and write absolute path of the page (/WebSite/Page2.aspx) in the Absolute path box and enter something in the Page Description box. You can well enter Text, HTML coded, CSS, JavaScript etc. into it and click Submit button. Try accessing the page for which you entered the record (http://localhost/WebSite/Page2.aspx) and you will see that your entered description is appearing, if you are not satisfied with the description go ahead and change it from your admin page (http://localhost/WebSite/admin/ListPage.aspx) still not satisfied? Play with it :) .





Hope this helps you managing static description or introduction of your pages and hassle of updating and uploading files on the server.

I know this is not the only way to achieve this task, but I find it easy and fast and it works for all pages of the website. If your website has no master pages you can well place it inside the .aspx pages but you need some extra effort of copy-pasting registering and calling the controls to all .aspx pages you want it on. If you have any questions, feedback or suggestions, do write to me.

Happy Coding and Enjoy!!!
Page copy protected against web site content infringement by Copyscape

About the Author

SheoNarayan
Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com
http://www.snarayan.com
Ex-Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan

Login to vote for this post.

Comments or Responses

Posted by: Parasu on: 8/29/2009
Sheo,

It's very useful to all webmasters, the way of explanations and everything good, keep posting like these types of articles for webmasters.

-Parasu.
Posted by: Shail12345 on: 11/1/2013 | Points: 25
Hello Sir
Your all articles nice but i implement that if i create Page1.aspx that come errors
Unknown server tag 'MyPage:pagedescription
plz solve my problem
thanks
Posted by: Sheonarayan on: 11/1/2013 | Points: 25
Hi Shail,

You will need to register the referenced .dll on the page, notice this statement in the article.

<%@ Register Namespace="TutorialsPageDesc" TagPrefix="MyPage" Assembly="MyControls" %>

Hope this helps.

Thanks

Login to post response

Comment using Facebook(Author doesn't get notification)