ASP. net2.0's navigation system does bring convenience to web development, but users who have used it will find that the navigation system has a major defect: You need to manually write the web. sitemap, Web. the syntax of sitemap is "quite simple", but in actual use, although simple, for a slightly complex navigation, you are certainly prone to errors. Below is a simple sitemap,
<Sitemap>
<Sitemapnode Title = "home" url = "~ /Default. aspx ">
<Sitemapnode Title = "Introduction to ASP. NET" url = "~ /Introduction/default. aspx ">
<Sitemapnode Title = "What's New in Whidbey? "Url = "~ /Introduction/whatsnew. aspx "/>
<Sitemapnode Title = "sample applications (starter kits)" url = "~ /Introduction/starterkits. aspx "/>
<Sitemapnode Title = "introduction to visual web developer" url = "~ /Introduction/vWD. aspx "/>
</Sitemapnode>
<Sitemapnode Title = "Building a web application" url = "~ /Development/default. aspx ">
<Sitemapnode Title = "Building a simple application" url = "~ /Development/simple/default. aspx ">
<Sitemapnode Title = "Introduction to ASP. NET pages" url = "~ /Development/simple/pages. aspx "/>
<Sitemapnode Title = "Introduction to server controls" url = "~ /Development/simple/servercontrols. aspx "/>
<Sitemapnode Title = "inline vs code behind pages" url = "~ /Development/simple/codeseparation. aspx "/>
<Sitemapnode Title = "Sharing code between pages" url = "~ /Development/simple/codedirectory. aspx "/>
</Sitemapnode>
</Sitemap>
To put it bluntly, it is just some nesting of sitemapnode, but the nested open-closed ECHO is a headache for people, but for computers, they like to deal with these simple relationships, so we can write a file so that the system can automatically retrieve the current application. Program And automatically generate the navigation.
First define some variables
// Private member
Private sitemapnode _ root;
Private string _ roottitle = "home ";
Private string _ rooturl = "~ /Default. aspx ";
Private bool _ usedefaultpageasfolderurl = true;
Private string _ defaultpagename = "default. aspx ";
Private cachedependency _ fsmonitor;
Private stringdictionary _ excludefilelist;
Private stringdictionary _ excludefolderlist;
Private char [] _ listseparator = {','};
Among these variables, the _ root variable stores the root directory of the site, and defines the _ roottitle and _ rooturl. These two variables are used to store the connection title and link address of the root directory.
You may find that I have also defined the cachedependency type _ fsmonitor. In this navigation, the cache technology is used and it is strongly recommended that you use the cache, because the site navigation will be used on various pages in the future, if the system automatically generates Navigation Based on the file list every time, the performance will be significantly affected. Therefore, cache is used here. The basic idea is: if the user does not change the page under the site, obtain the navigation information directly from the cache. Otherwise, the site navigation will be regenerated. After the new navigation is generated, a copy will also be copied to the current cache.
There are two variables above: _ excludefilelis and _ excludefolderlist. As the name suggests, these two variables indicate that I want to exclude files and folders in the navigation in the future. What does it mean?
Because we allow the system to enumerate all files under the root directory, the system will generate all Site Navigation Based on all files under the directory by default, which obviously does not fully meet our needs.
The Code You can find the following code:
String folder = httpcontext. Current. server. mappath (folderpath );
Directoryinfo dirinfo = new directoryinfo (folder );
Foreach (fileinfo fi in dirinfo. getfiles ("*. aspx "))
{
Sitemapnode filenode = createfilenode (Fi. fullname, parentnode, folderpath );
If (filenode! = NULL)
Addnode (filenode, parentnode );
}
Foreach (directoryinfo di in dirinfo. getdirectories ())
{
Sitemapnode foldernode = createfoldernode (Di. fullname, String. Concat (folderpath,
Di. Name, "/") + defapagpagename );
If (foldernode! = NULL)
Addnode (foldernode, parentnode );
Buildsitemapfromfilesystem (foldernode, String. Concat (folderpath, Di. Name ,"/"));
}
This Code shows that the generated navigation is actually to enumerate the aspx pages under each folder, but sometimes we do not want it to enumerate the aspx pages in all directories, including app_code, images, etc, if any) and other aspx pages that do not want the system to display for security purposes,
_ Excludefilelis and _ excludefolderlist may tell the system which files should be excluded from the navigation.
The values of _ excludefilelis and _ excludefolderlist are from web. config. You can add the following configuration in Web. config:
<Add name = "filesystemsitemapprovider"
Type = "filesystemsitemapprovider"
Excludefilelist = "default1.aspx, default2.aspx"
Excludefolderlist = "myfiles, myfile2"
/>
By exposing two interfaces for external exclusion files in Web. config, you can easily configure the actual generation requirements of navigation.
The following code is displayed in the Code:
Public void refresh ()
{
_ Root = NULL;
Base. Clear ();
}
As mentioned above, in order to improve performance, the cache technology is used. When the cache becomes invalid, refresh will be called to refresh the system. This invalidation is achieved by calling base. Clear ();.
The buildsitemap function is used to construct site navigation. This is the core function for navigation. The code for this function is as follows:
Public override system. Web. sitemapnode buildsitemap ()
{
Lock (this)
{
If (_ root! = NULL)
If (! _ Fsmonitor. haschanged)
Return _ root;
Refresh ();
_ Root = createfoldernode (httpcontext. Current. server. mappath (rooturl), rooturl );
_ Root. Title = roottitle;
_ Fsmonitor = new cachedependency (httpcontext. Current. server. mappath ("~ /"));
Addnode (_ root );
Buildsitemapfromfilesystem (_ root ,"~ /");
Return _ root;
}
You can find that
Lock ()
{
}
Locking, because we want the system to perform operations similar to "transactions in the Database" during the update process. The most fundamental reason is the concurrency of user requests.
The custom provider model is used in this navigation. To simplify development, we use the filesystemsitemapprovider class, which is derived from the staticsitemapprovider class, which is also a recommended mode by Microsoft. Add the following configuration in Web. config:
<Sitemap enabled = "true" defaultprovider = "filesystemsitemapprovider">
<Providers>
<Add name = "filesystemsitemapprovider"
Type = "filesystemsitemapprovider"
/>
</Providers>
</Sitemap>
You can.
The following figure shows the basic mode for a page (*. aspx) to use.
<Asp: Treeview id = "treeview1" runat = "server" performanceid = "sitemapperformance1"
Imageset = "xpfileexplorer"
Nodeindent = "15" showlines = "true" maxdatabinddepth = "5">
<Parentnodestyle font-bold = "false"/>
<Hovernodestyle font-underline = "true" forecolor = "# 6666aa"/>
<Selectednodestyle backcolor = "# b5b5b5" font-underline = "false"
Horizontalpadding = "0px"
Verticalpadding = "0px"/>
<Nodestyle font-names = "tahoma" font-size = "8pt" forecolor = "black"
Horizontalpadding = "2px"
Nodespacing = "0px" verticalpadding = "2px"/>
</ASP: Treeview>
<Asp: sitemapdatasource id = "sitemapdatasource1" runat = "server"/>
As you can see, the procedure is as follows:
1) place an ASP: sitemapdatasource on the aspx page without any settings.
2) use Treeview (menu,...) to set its performanceid to sitemapdatasource1.
This is simple. By the way, if you suddenly want to use the default web. sitemap file, as the simplest processing method, only need to change the web. the defaultprovider in config is xmlsitemap.
Download and describe the code in this article
This is done Source code If you need to use the file in your project, just copy the file to the app_code directory of the application (change the extension to the CS file ).