tells ASP.NET to look for a section in the app/web.config file called 'googlesitemaps'. The type attribute is in the format of type="typeName, assemblyName", and tells ASP.NET that there is a type called 'GoogleSiteMapSection' in the Assembly 'iFinity.GoogleSiteMapProvider'. The GoogleSiteMapSection type derives from System.Configuration.ConfigurationSection and provides the run-time type to represent the Providers section in the config file. This is all done at run time by the ProviderBase class. The next entry to make in the web.config file is the actual 'googlesitemaps' section that was named in the entry. This should be done after the closing tag of the section, but before the end of the section.
This entry tells ASP.NET which providers are available to use at runtime. If anything else but the default provider is to be used, the calling code would have to be modified to do so. However, to change the default provider to be used, the defaultProvider attribute just needs to match the name of a provider in the list.
The final change to make to the web.config is the addition of the HTTP Handler to actually produce the Site map. This is done in the web.config within the system.web section, under the httpHandlers section.
type="iFinity.Providers.GoogleSiteMap.GoogleSiteMapHandler,
iFinity.GoogleSiteMapProvider"/>
This entry tells any incoming requests for 'GoogleSiteMapHandler.axd' to load up the iFinity.GoogleSiteMapProvider Assembly and call the type of 'iFinity.Providers.GoogleSiteMap.GoogleSiteMapHandler'. This is done automatically by ASP.NET for you, as long as the specified type implements the IHttpHandler interface (which this does).
Please note that the Handler doesn't need to be in the provider, and in a way, including the Handler Type within the Provider model pollutes it slightly. By rights the Handler should call the ASP.NET ProvidersHelper namespace to give it back the correct Provider for that configuration. To be completely correct the Handler type and the GoogleSiteMapService type should be in a separate namespace and Assembly. But as I intend to create separate Assemblies for providers down the track, I'm happy to live with my model. Others may claim it incorrect, and they have a valid point.
Program flow
When a Http request is made for GoogleSiteMapHandler.axd (either by the Google crawler, or by typing in 'yoursite.com/googleSiteMapHandler.axd' into a browser), ASP.NET loads up the named type/assemby in the httpHandlers web.config section. In this instance it is the same DLL as the Provider, though it doesn't need to be as discussed previously. ASP.NET calls ProcessRequest(HttpContext context) as any type implementing IHttpHandler must have. This then calls the GoogleSiteMapService.GetGoogleSiteMap() method, which then asks ASP.NET for the default provider as named in the googlesitemaps configuration section.
ASP.NET reads in the providers and instantiates an object of the type named as the default provider. This provider object is then asked for the XML that makes up the site map. As the Assembly also includes a basic implementation of the default provider, it is this provider that is called. The base implementation in the demo project simply iterates the directories and reads in all of the files that match the named extension in the sitePageTypes attribute. This XML is then passed back up through the call stack and returned as XML through the HTTPHandler, resulting in XML being output either to the browser or the Google crawler.
Expansion Possibilities
As mentioned before, this project was made with the intent of developing a better understanding of the provider model, and providing a base implementation that can be expanded to better handle more complicated ASP.NET application models.
To expand this code, there are two possible directions. The first, and simplest, is to just modify the code in the GoogleSiteMapProvider IteratePages() procedure. This can be modified in order to better provide a site map for a particular site - the possibilities are quite open in this respect.
The second, and conceptually better but slightly more complicated, is to simply reference the provided Assembly and create your own provider by inherting from the GoogleSiteMapProvider type. You will need to redefine the IteratePages() in the derived class to index the pages in the site in a better method, but everything else can be left as is. The new provider would be compiled into a separate Assembly and then named as the default provider in the googlesitemaps configuration section.
For instance, let's say you create new provider class called 'MyNewGoogleSiteMapProviderType'and compile it into an assembly called 'MyNewGoogleSiteMapProviderAssembly.dll'. The config entry would be:
type="MyNewGoogleSiteMapProviderType, MyNewGoogleSiteMapProviderAssembly"
defaultPagePriority="0.5" defaultPageUpdateFrequency="daily"/>
This would mean that your new type would be called to provide the list of pages for the website. The Base provider would take care of formatting it into the SiteMap format and outputting the XML. You can leave all the other web.config entries as is - the built in HttpHandler would take care of calling your provider for the list of pages in your site. How you provide that list is up to you!
What's Next
I will be developing a new implementation of the provider model to suit DotNetNuke, as this is the platform I do a lot of development in. DotNetNuke uses a HttpRedirection method to serve many URLs from a single default.aspx page, and as such can't be used to generate a sitemap from physical files.
I will then create different providers for each of the separate specialised modules that I use in DotNetNuke websites. Some modules provide a wide range of different content for the one URL, depending on database-driven content. With conventional Google indexing, much of the content may not be found and indexed correctly.
Copyright notice
You are free to use, modify and extend the supplied code provided that you do not remove the copyright messages in the source, or attempt to pass either the code or this article off as your own. Obviously with free demo code there's no warranty that it will actually work and there may be bugs in the provided download.
If you use this code and find it useful, I appreciate links back to my website, www.iFinity.com.au.
Download the Demo Version (16kb)
Download the Source Code (11kb)
This Article is also published on 'The Code Project' and various ASP.NET Forums