Guy Harwood

UK based developer who
loves the Morecambe sunset

SEO Manager for ASP.NET - manage your meta tag and sitemap generation from one place

When asp.net 2 arrived i was very pleased to see full support included for accessing the head section of a page programmatically.  This meant i could now access and add all the meta tag information dynamically.  Recently i started looking into dynamic sitemap generation and picked up a wealth of good tips from Cristian Darie and Jaimie Sirovichs' excellent book on SEO for Asp.Net - including a basic implementation of a sitemap http handler. 

 
I decided to blend the management and generation of the meta tags and sitemap into one set of tools that could be easily implemented into any asp.net site.

Screenshot of pageManager.aspx

pageManager.aspx

How it works

PageManager allows you to add meta tags to pages within your site and specify whether or not the page should be included in the sitemap.  This is all stored in a sql server database, and the tables can easily be imported into an existing site.

When a page loads it performs a query against tblPage to see if an entry exists for a page with its name (including any paths after the domain name for uniqueness of course).  if it does it then proceeds to load any meta tag data into its header, and a custom page title if one is present.

Sitemap.ashx generates an xml sitemap of all the pages from tblPage flagged as 'include in sitemap' via pageManager.aspx.  The sitemap is based on the sitemaps.org standard , but only includes a minimal amount of information (such as page priority). 

But most of my pages are data driven - did you think about that?

Yes, most of mine are too..

The sitemap generator uses reflection to load a custom class that you create, which implements a single method - returning a custom generated list of sitemap entries

For example...

lets say you have product.aspx (as included in the example project download below) and it accepts a simple parameter that determines which product to display on the page. such as mysite.com/product.aspx?productID=1544

Simply create a class that implements ICustomPageInfo and implement its only member - GetCustomPageItems() As List(Of SitemapItem)

The purpose of this function is to return a List of sitemapitems for insertion into the generated sitemap instead of 1 parameterless link to product.aspx.  So ideally, you would scan the products table, pick out the product pages you want indexed and return those urls as a list of sitemap items.

The only other thing you have to do is specify the fully qualified name of this class you have created in the 'Custom Call' box in pageManager for the page in question and the sitemap handler will append these to the generated sitemap automatically.

For an example of this, see the ProductSitemapInfo class in the example project download below.

I have already set this up in the attached mdf example database.

But what about specific meta tags for these data driven pages?

I implement these at product level within the system, so the user adding/editing the product would insert a heap of keywords specific to the product in question.   When that product is loaded into product.aspx i populate the keywords and description meta tags from the product record in the database, essentially overriding the insertion at basepage level from tag data specified in pageManager.  You can easily extend this by creating a 'populate_header' event in the basepage, subscribing to this at page level and inserting your custom keywords/tags right there and then. 

This is how i do it in some of the sites i have developed.

But i dont use Query strings in my pages?

If you understand how this works then surely you can work out the rest yourself :-P

The Contents of the example project

admin/pageManager.aspx - where you set what pages to include in the sitemap and what meta tags to pump into each page you want indexing.

App_Data/pageManager.mdf - the database used as an example (includes the products table from Northwind :-P )

code/basepage.vb - you may have one already - so do i.  This just contains the basic hook into the page_load event to populate the necessary meta tag information and title - if found in the database.

code/db.vb - database access code, just to save you the time of rolling your own if you choose to download the demo project and want to run it.

code/ICustomPageInfo.vb - an interface to allow multiple sitemap url generation for data driven pages (explanation below)

code/PageInfo.vb - a helper class for the page data, quite basic but easily extended.  I will no doubt rewrite this based around LINQ very soon (time permitting :-S)

code/ProductSitemapInfo.vb - an example implementation of ICustomPageInfo for the product.aspx page

code/siteMapItem.vb - simple helper object that holds sitemap url information

code/util.vb - just some utility functions for generic stuff like web.config access etc...

default.aspx - do i really have to explain this one? :-P

product.aspx - a data driven page that shows an individual product based on the id passed in via query string.

siteMap.ashx - the http handler that returns the xml sitemap.

Its Basic

Yes, there are quite a lot of things that can be done to extend this, some of which i have already done and used in live sites, for example....

Create a specific basepage method that can be overridden to allow extra tags/keywords to be appended/inserted at page level

use LINQ to query the aspx pages that populate the treeview in pageManager.aspx (not really necessary but hey its new!)

Use caching to store specific page tags after first retrieval.

The gridview for adding metatags is pretty mediocre, but serves as an example, ok? :-P

 

I hope you find this tool to be beneficial like i have. 

The core of it is currently in use on live sites that rank well in their area, and it saves a lot of manual work when we need to modify our keywords and add pages to the sitemap.

kick it on DotNetKicks.com

Download

Both versions come with a populated database dumped from SQL Server 2000, and also a create database script if you want to start from scratch.  The tblProduct table comes directly from Northwind. 

Vs2008 .Net 3.5 in Visual Basic.NET Download

Vs2008 .Net 3.5 in C# Download

note - some of the directory parsing code originates from this post by Scott Mitchell

Comments

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# April 24, 2008 11:34 AM

superjason said:

Why didn't you put the data into the standard ASP.NET sitemap? If you're using an XML site map, you could add some custom nodes.

We're using a SQL server based sitemap provider, and we added them in there.

It's just nice for a fully integrated solution.

Just a suggestion for a future version. :-)

Good job!

# April 24, 2008 1:26 PM

mikedopp said:

Any chance of the source code in C#?

# April 24, 2008 1:53 PM

Guy Harwood said:

@Jason...

thanks,

never looked at the sitemap control, maybe i should :)

@Mike...

C# Version of the code is nearly complete, will post it up asap.

# April 24, 2008 2:44 PM

Grant Palin said:

Nice!  I was thinking about doing something similar for one of my projects.  I will take a look at the provided code tonight, just for inspiration :)

# April 24, 2008 4:02 PM

mikedopp said:

@guy,

You rock thanks for the C# code as well as the information.

mikedopp

http://blog.mikedopp.com

# April 25, 2008 12:13 PM

Jon said:

When are you going to release the C# version? the link you've provided above is VB

# April 25, 2008 2:52 PM

Guy Harwood said:

Sorry guys,

link updated and now pointing to C# Version.

# April 25, 2008 4:04 PM

Chris Love's Official Blog - Professional ASP.NET said:

OK, so this is a little more than a week. Sorry I have been very busy since getting back from Seattle.

# April 30, 2008 7:54 AM

Eduardo said:

Hi, these two link are currently not working.

Would you mind fix these?

Thanks in advance!

# June 11, 2008 1:20 PM

Guy Harwood said:

will get the links updated asap

# June 11, 2008 2:35 PM

Guy Harwood said:

links updated :)

# June 11, 2008 2:59 PM

Hi said:

Hi

It helpful for me

Thank

# August 9, 2008 1:42 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)