Data Tutorial #2: Building our Master Page and Site Navigation Structure

June 22nd 2006 Update: We've now published a whole series of new data tutorials based on this origional post.  You can read all about it here.

 

This past weekend I posted a step-by-step tutorial on how to build a strongly-typed DAL (data access layer) using Visual Web Developer (which is free) and ASP.NET 2.0.

 

My plan over the next few weeks is to post many follow-up samples that show various ways to use this DAL to build common data scenarios using ASP.NET 2.0 (master details, filtering, sorting, paging, 2-way data-binding, editing, insertion, deletion, hierarchical data browsing, hierarchical drill-down, optimistic concurrency, and more).

 

Before doing that, I wanted to setup a common site structure to help organize all of these samples.  I wanted to make sure that all the samples in the site shares a consistent look and feel, and that the site has an easy to navigate site structure.  Thankfully this is now very easy using the new ASP.NET 2.0 Master Page and Site Navigation features (and can be done without having to write any code).

 

Here is a screen-shot of the sample site skeleton I put together:

 

 

You can download the site sample here.  The below set of tutorials walks-through how I built it:

 

Step 1: Adding a master page

 

Below is the basic site structure we were left with after building our data acess layer for the Northwinds database in my previous blog post.  It has a strongly typed DAL that goes against the Northwinds database:

 

 

What I want to-do now is add a Master Page to the site.  Master Pages is a new feature in ASP.NET 2.0 that enables me to define a common layout structure and look and feel that I can easily apply to multiple (or all) pages across a site/app. 

 

To add a Master Page, right click on the project and choose “Add New Item”.  Pick the Master Page Template from the “Add New Item” dialog and name it “Site.Master”:

 

 

I want my site to use a CSS based layout approach.  As such, I am using <div> elements to organize the structure (as opposed to <table> elements).  Here is the HTML I added:

 

<%@ Master Language="VB" CodeFile="Site.master.vb" Inherits="Site" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>Northwind Data Samples</title>

    <link rel="stylesheet" type="text/css" href="stylesheet.css" />

</head>

 

<body>

    <div id="wrapper">

 

        <form id="Form1" runat="server">

 

              <div id="header">

                  <span class="title">Northwind Data Tutorials</span>

                  <span class="breadcrumb">Todo: Breadcrumb will go here...</span>

              </div>

           

              <div id="content">

                <asp:ContentPlaceHolder ID="MainContent" runat="server">

                </asp:ContentPlaceHolder>

              </div>

                 

            <div id="navigation">

                Todo: Menu will go here...

            </div>

           

        </form>

    </div>

 

    <div id="footer">

        <a href="http://weblogs.asp.net/scottgu">http://weblogs.asp.net/scottgu</a>

    </div>

</body>

</html>

 

Notice the <asp:contentplaceholder> control that is in the middle <div> element.  This is a new ASP.NET 2.0 control that I can use to define regions of the master template that can be “filled-in” or replaced by pages that use this master.  You can have any number of <asp:ContentPlaceHolder> controls you want within a master-page – all you need to-do is make sure that each has a unique “id” value.  For the sample above I’ve added one <asp:contentplaceholder> and named it “MainContent” (since it will be where pages on the site fill in their content).

 

I am also then using an external CSS stylesheet (“stylesheet.css”) to define the CSS for the page.  When in design-view the Master Page looks like this:

 

 

Step 2: Create a Home Page based on the Master Page

 

Now that I have my Master Page defined, I can go ahead and build pages using it.  To build one, right click on the Project and choose “Add New Item”, and select the “Web Form” item:

 

 

Notice that I’ve selected the “Select master page” checkbox near the bottom of the dialog.  This tells Visual Web Developer that you want to have this new page use a Master Page.  When you click the “add” button it will then ask you to pick the Master Page to use:

 

 

When I select the “Site.Master” file we defined above, it will create a new Default.aspx file like so:

 

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" title="Untitled Page" %>

 

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">

</asp:Content>

 

Visual Web Developer has automatically added an <asp:content> control for the “MainContent” contentplaceholder we defined earlier (note the “ContentPlaceHolderId attribute defines which contentplaceholder we want to override).  I can then fill this content region in with the unique content I want to add to the page:

 

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" title="Home" %>

 

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">

 

    <h1>Welcome to the Northwind Data Samples Site</h1>

 

    <p>This site is being built as part of a set of tutorials that show off some of the new data access

    and databinding features in ASP.NET 2.0 and Visual Web Developer.</p>

   

    <p>Overtime, it will include a host of samples that demonstrate: building a DAL (data access layer)

    using strongly typed TableAdapters and DataTables, master details, filtering, sorting,

    paging, 2-way data-binding, editing, insertion, deletion, hierarchical data browsing,

    hierarchical drill-down, optimistic concurrency, and more. </p>

   

    <p>Please subscribe to <a href="http://weblogs.asp.net/scottgu">http://weblogs.asp.net/scottgu</a>

    to follow along as they are published.</p>

 

</asp:Content>

 

Note that the page will automatically pick up the CSS stylesheet from the master-page (ASP.NET will also automatically “rebase” the CSS url when the .aspx page is in a sub-directory – so you don’t have to worry about fully qualifying the style-sheet or doing weird “../” hacks).

 

Note also that I have set the “Title” attribute on the <%@ Page %> directive to “Home”.  This attribute allows me to declaratively provide the page title, even though the <head> element is defined within our Master Page.

 

When I switch into design-view on the page, Visual Web Developer will automatically show me a merged view of the page that combines both the Master Page and deriving Page:

 

 

ASP.NET will also merge the content together at runtime – and send down a single html page when a browser requests this page.  The beauty of this model is that the Master Page layout is defined in one single place – so if I need to make a change I can update one file, and have every file that is based on it within the site immediately update.

 

Step 3: Adding More Pages to the Site

 

I can use the Master Page to quickly build several more pages for the site.  Specifically, I decided to add two top level section pages “Basic Data Scenarios” and “Advanced Data Scenarios” that I think I might want to use to group several samples around.  I then built several stub sample pages in directories that will live within them.

 

After adding many files to the project (all based on the Master Page file), my directory structure looks like this:

 

 

Step 4: Defining a Site Map for the Site

 

One challenge I am going to have as I build-out my site is keeping the organizational structure of it in shape (especially if I keep adding samples each week).  I’m going to want to have some type of menu system that helps users on the site navigate their way around.  What I want to make sure I avoid is having to manually build and then update this menu structure within HTML every-time I make a change.  Instead, what I want to-do is to define the site link structure with a clean data-model that I can then dynamically data-bind my UI against.  The good news is that ASP.NET 2.0 makes this easy with the new Site Navigation system.

 

Using the Site Navigation system I can define the logical “site map” structure of what my site looks like – specifically how the site structure is logically laid out (this can be different to how they are physically organized on disk), and how the different pages are organized in relation to each other.  I can then access this structure at runtime using the new “SiteMap” property on each ASP.NET page and user-control.  What is powerful about this API is that I can also use it to keep track of where the current request is within the site structure – as well as dynamically lookup a request’s relation to other urls within the site (for example: what is the “parent, “sibling” and “child” nodes in the site-map relative to the current request).   Even fancier, I can integrate the Site Map system with the new ASP.NET 2.0 Role Management security features – so that I can view the structure through the “trimmed view” of what a visiting user has permission to see (for example: pages that are secured only for users in an admin role wouldn’t show up in the Site Navigation model when a guest is visiting the site).  The combination of all these features makes it very easy to quickly build menu navigation and bread-crumb UI.  You can also use this module to help your site integrate better with search engines like Google.

 

To define our Site Navigation structure, I’m going to use the built-in XML Site Map Provider that ships with ASP.NET 2.0.  Alternatively, if I wanted to store the site-map structure in a database I could have configured my site to use the cool new SQL Site Map Provider (the beauty of the ASP.NET 2.0 provider model is that all the code and data-binding logic to work against the Site Navigation system stays the same regardless of which provider implementation you have configured). 

 

The XML-file based provider uses XML files that by default have the name “Web.SiteMap” to define the site hierarchy.  To create one of these files, right click on the project and choose “Add New Item” and the “Site Map” item:

 

 

This will create an XML file with a default schema for defining a site-layout.  Note that Visual Web Developer provides automatic intellisense for this XML structure.

 

For my particular sample, I choose to define the site structure like so:

 

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

 

    <siteMapNode url="Default.aspx" title="Home"  description="Home">

     

        <siteMapNode url="Samples_Basic/BasicSamples.aspx" title="Basic Data Samples"  description="Basic Data Samples">

          <siteMapNode url="Samples_Basic/Sample1.aspx" title="Samples 1"  description="Samples 1" />

          <siteMapNode url="Samples_Basic/Sample2.aspx" title="Samples 1"  description="Samples 2" />

          <siteMapNode url="Samples_Basic/Sample3.aspx" title="Samples 1"  description="Samples 3" />

          <siteMapNode url="Samples_Basic/Sample4.aspx" title="Samples 1"  description="Samples 4" />

        </siteMapNode>

 

        <siteMapNode url="Samples_Advanced/AdvancedSamples.aspx" title="Advanced Data Samples"  description="Advanced Data Samples">

          <siteMapNode url="Samples_Advanced/Sample1.aspx" title="Samples 1"  description="Samples 1" />

          <siteMapNode url="Samples_Advanced/Sample2.aspx" title="Samples 1"  description="Samples 2" />

          <siteMapNode url="Samples_Advanced/Sample3.aspx" title="Samples 1"  description="Samples 3" />

          <siteMapNode url="Samples_Advanced/Sample4.aspx" title="Samples 1"  description="Samples 4" />

        </siteMapNode>

 

        <siteMapNode url="About.aspx" title="About"  description="About" />

 

    </siteMapNode>

 

</siteMap>

 

It has a top-level node called “Home” – and then three sub-nodes – “Basic Samples”, “Advanced Samples” and “About”.  The “Basic Samples” and “Advanced Samples” then have several sub-nodes beneath them. 

 

Note that ASP.NET will automatically cache the Site Maps’ XML file so that it doesn’t get read on each request – instead it will only be parsed and processed on the first request to the application, and then on subsequent requests the cached version will be used (note: this will automatically get re-generated anytime the file changes).

 

I can then programmatically use the SiteMap.CurrentNode property within an ASP.NET page at runtime to get back a SiteMapNode object that represents where the current request is within the above Site Map definition – as well as what its parent, children, and sibling node urls are (and what their friendly names are as well).

 

Step 5: Data-Building a Site Navigation Menu Structure

 

ASP.NET 2.0 introduces a new concept called “data source” controls – which are control objects that provide a standard way to expose data that UI controls can then bind against.  The data source model is extensible, so you can easily build your own Data Source controls to plug into the system (this blog post points to how to-do this).  One of the built-in data-source controls that ASP.NET 2.0 ships with is the <asp:sitemapdatasource> control – which makes it super easy to databind any UI controls against the Site Navigation data model.

 

ASP.NET 2.0 ships with built-in <asp:treeview> and <asp:menu> controls, which can be used to create menu and tree-view structures based on the site-map structure.  To add and then data-bind the <asp:menu> control to a <asp:sitemapdatasource> control on a page, I could simple add this markup to the Site.Master file (replacing the previous to-do menu comment):

 

<div id="navigation">

<asp:Menu ID="foo" DataSourceID="SiteMapDataSource1" runat="server">

</asp:Menu>

               

      <asp:SiteMapDataSource ID="SiteMapDataSource1" ShowStartingNode="false" runat="server" />

</div>

 

I would then have a fly-out menu for navigating around the site.

 

Alternatively, if I want even greater control over the HTML generated, I could use more basic (but also more flexible) controls – like the ASP.NET Repeater control. 

 

For example, I could use the <asp:repeater> to create an html <ul></ul> list like so:

 

<div id="navigation">

    <ul>

        <li>

            <a href="default.aspx">Home</a>

        </li>

   

        <asp:Repeater ID="foo" DataSourceID="SiteMapDataSource1" runat="server">

            <ItemTemplate>

                <li>

                    <a href='<%#Eval("url") %>'><%#Eval("Title") %></a>

                </li>

            </ItemTemplate>

        </asp:Repeater>

    </ul>

</div>

 

<asp:SiteMapDataSource ID="SiteMapDataSource1" ShowStartingNode="false" runat="server" />

 

With our Web.SiteMap file defined like it is above, this would then generate the below html at runtime:

 

<div id="navigation">

    <ul>

        <li>

             <a href="default.aspx">Home</a>

        </li>

        <li>

              <a href='/DALWalkthrough/Samples_Basic/BasicSamples.aspx'>Basic Data Samples</a>

        </li>

        <li>

             <a href='/DALWalkthrough/Samples_Advanced/AdvancedSamples.aspx'>Advanced Data Samples</a>

        </li>

        <li>

             <a href='/DALWalkthrough/About.aspx'>About</a>

        </li>

    </ul>

</div>

 

If I wanted to show the next level of hierarchy in the SiteMap as well, I could add another <asp:repeater> within the first one to also generate a sub-hierarchy of <ul><li><ul> elements.  For example:

 

<asp:Repeater ID="foo" DataSourceID="SiteMapDataSource1" runat="server" enableviewstate="false">

    <ItemTemplate>

        <li>

            <a href='<%#Eval("url") %>'><%#Eval("Title") %></a>

           

            <ul>

                <asp:Repeater ID="bar" DataSource='<%#Container.DataItem.ChildNodes() %>' runat="server">

                    <ItemTemplate>

                        <li><a href='<%#Eval("url") %>'><%#Eval("Title") %></a></li>

                    </ItemTemplate>

                </asp:Repeater>

            </ul>

 

        </li>

    </ItemTemplate>

</asp:Repeater>

 

Note that VB allows me to write Container.DataItem.ChildNodes() as a direct data-bound expression.  In C# I would need to cast like so: ((SiteMapNode) Container.DataItem).ChildNodes()

 

This would then generate the below HTML markup:

 

<div id="navigation">

    <ul>

        <li><a href="default.aspx">Home</a></li>

        <li><a href='/DALWalkthrough/Samples_Basic/BasicSamples.aspx'>Basic Data Samples</a>

            <ul>

                <li><a href='/DALWalkthrough/Samples_Basic/Sample1.aspx'>Samples 1</a></li>

                <li><a href='/DALWalkthrough/Samples_Basic/Sample2.aspx'>Samples 1</a></li>

                <li><a href='/DALWalkthrough/Samples_Basic/Sample3.aspx'>Samples 1</a></li>

                <li><a href='/DALWalkthrough/Samples_Basic/Sample4.aspx'>Samples 1</a></li>

            </ul>

        </li>

        <li><a href='/DALWalkthrough/Samples_Advanced/AdvancedSamples.aspx'>Advanced Data Samples</a>

            <ul>

                <li><a href='/DALWalkthrough/Samples_Advanced/Sample1.aspx'>Samples 1</a></li>

                <li><a href='/DALWalkthrough/Samples_Advanced/Sample2.aspx'>Samples 1</a></li>

                <li><a href='/DALWalkthrough/Samples_Advanced/Sample3.aspx'>Samples 1</a></li>

                <li><a href='/DALWalkthrough/Samples_Advanced/Sample4.aspx'>Samples 1</a></li>

            </ul>

        </li>

        <li><a href='/DALWalkthrough/About.aspx'>About</a>

        </li>

    </ul>

</div>

 

I can then use a standard CSS styling approach to customize the look and feel of this structure however I want.  Rachel Andrew has a great book that I use called “The CSS Anthology: 101 Essential Tips, Tricks & Hacks” that provides a really nice scenario based tutorial approach to using CSS.  I used a technique she came up with in chapter 4 to make the markup above look like this when I add some CSS to my StyleSheet.css file:

 

 

And now I have a nice looking menu for my site, data-bound to the Site Navigation system, which is in turn data-driven from my web.sitemap file.

 

Step 6: Adding a “Breadcrumb” navigation control to the page

 

The last touch I want to add to my site is support for a “bread-crumb” UI paradigm near the top of the page that will help users easily figure out where they currently are within the application.  The good news is that this is super easy with ASP.NET 2.0 and the Site Navigation system.

 

All I need to-do is add the new <asp:SiteMapPath> control to my “header” <div>:

 

<div id="header">

    <span class="title">Northwind Data Tutorials</span>

    <span class="breadcrumb">

        <asp:SiteMapPath ID="Breadcrumb"  runat="server"></asp:SiteMapPath>

    </span>

</div>

 

This will then output the site hierarchy of the current node relative to the root node of the site map.  For example, if I was on “Sample1” within the “Basic Data Samples” section of the site, the above control would automatically output this:

 

 

If I click on the “Basic Data Samples” hyperlink (which is automatically generated by the breadcrumb – or I could just use the menu link), it would adjust to:

 

 

No code is required.

 

Summary

 

I now have the basic site structure and layout defined for the sample site I am going to use to build my data samples.  It has a consistent, centralized, layout and look and feel structure by using the new ASP.NET 2.0 Master Page feature.  And my site and link structure is nicely encapsulated by the ASP.NET 2.0 Site Navigation system, which I’m also using to dynamically generate a navigation menu and breadcrumb UI for the site:

 

 

Best of all, I didn’t need to write any code to enable this, and I still get full WYSIWYG designer support within Visual Web Developer.

 

Hope this helps.  Lots of data samples are now going to follow…

 

Scott

 

Published Tuesday, January 17, 2006 11:41 PM by ScottGu
Filed under: , ,

Comments

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 3:38 AM by Jack
good job scott, thx a lot, now i'm looking forward the following posts...!

Jack

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 5:00 AM by Tarun
Hi Scott,
Great Article!!
I wish your blog has a feature for each post to view in a print mode.
That would rock.

Thanks

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 5:48 AM by cowgaR
Hi Scott,

these series of 'cook' articles from you is very nice (and rare), but it would be good if you provide some 'riddles' and extensions hints at the end...

like homework - to do:

- build an antigravitation layer that easy all but DB calls
- extend business layer so that any Lawyer entering site will die the moment he see the 2nd picture
- transform all UI calls to log that you can see what is the most interesting feature on your site

just joking, but something similar would be nice, simply some challenge for asp.net developers. Then after 'completing' article we can fiddle with the example and find out where the more serious problems are, and got better at understanding and SELF coding skill.

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 11:32 AM by Mike
Hi Scott, great article as usual.
for C# you may want to remove the parentesis at the end, since is a property:
((SiteMapNode)Container.DataItem).ChildNodes

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 12:22 PM by scottgu
Hi Mike,

Good point (for some reason I thought it was a mathod). Better yet, you cna actually just simplify the expression for both VB and C# to just:

<%# Eval("ChildNodes") %>

Thanks,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 2:17 PM by Kyle
Great article Scott...

Quick question - I would like to bind to the sitemap and access the generated links on the client-side through atlas/javascript. However, I am unable to do this b/c System.Web.SiteMapNode does not have an 'id' property. Any suggested workarounds? Do you know how I might specify and access an 'id' property for a given sitenode?

Thanks,
Kyle

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 2:33 PM by scottgu
Hi Kyle,

Are you trying to bind to the anchor elements within the <asp:repeater> template? If so, the easiest way to get unique IDs would be to mark and <a> tags with a runat=server attribute on them. This will provide a unique id value for each of them.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 3:46 PM by scottgu
Hi Kyle,

You might consider using the "description" attribute in the SiteMapNode if you want to store and output a unique id value. That way you could do what you want above -- and just use Eval("description") to get it out.

My suggestion with the marking the <a> tag runt=server was more so that you'd get a unique id for each element (doing this would cause ASP.NET to render a client-side ID element that was unique). If you want more control over the exact names, though, you might want to instead use the description idea instead.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 3:51 PM by LukCAD
Scott!
Seems i found this error in my code only.
When i repeated your lesson step by step I typed the standart hyperlink for HOME menu without runat="server" into tag of html code.
So All is OK.
Sincerely, LukCAD

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, January 18, 2006 3:55 PM by scottgu
Hi LukCad,

Yep -- there is a slight bug in my markup above (although I fixed it for the sample -- so the .zip file is fine).

Basically, the issue is when you have a page that is based on the Site.Master that lives in a sub-directory. I had a <a href="default.aspx"> that was a non-server control -- whose relative link was obviously broken if emitted in a different directory from the default.aspx page.

There were two ways to fix it:

1) Root qualify it (for example: /default.aspx)

2) Add a runat=server attribute to the anchor -- in which case asp.net will fix up the path to be relative to the site.master and not the sample1.aspx page based on it.

In the .zip file I did approach #2 -- since that handles the scenario where the site is not a root site on a box.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, January 20, 2006 6:51 AM by David Taylor
Scott,

Data Binding feature needed in ASP.NET 2 or 3:

I initially added this as a comment to one of Fritz's blog entries. But this is a really good idea, so wanted you to think about it...

I must say that one of this things Microsoft seem to have missed is the concept of an <asp:PropertyParameter />.

Why do I think this is missing and important? Because you often get in a "pull" mindset with the new databinding model where you want to setup Data Source Parameters to pull their values from Session, Profile, QueryString, or another Control (etc). But it often breaks down and you need to use the "push" ie Event handling model, which makes the code harder to comprehend. For certain unsupported scenarios you end up needing to wire up an event handler and changing the data source properties DefaultValue, or alternatively setup the value on the Inserting or Modifying event.

Wouldn't it be elegant to just define a couple of Page level properties like:
public DateTime Today
{
get { return DateTime.Now; }
}

public string UserName
{
get { return User.Identity.Name;
}

and then just include a new property param like:
<asp:PropertyParameter Name="filed_by" Property="UserName" />
<asp:PropertyParemeter Name=date_filed" Property="Today" />

This would allow you to keep within a single "pull" mindset when wiring up databinding logic.

Another reason you *need* this feature, is because ASP.NET 2 is really bad when splitting stuff between different user controls or between a masterpage and a page or user control. The data binding stuff in V2 seems really bad unless both the data source and data control are hosted within the same page/control. For example, you cannot have a control within one user control, used as a ControlParameter for a DataSource control within a different user control. Adding a PropertyParameter and creating a page level property would be a very elegant solution to this type of problem?

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, January 20, 2006 10:57 AM by Pat King
Hi Scott,

Great Example!

I want to know is there a way to make the site navigation structure expand and collapse, especially on the "Basic Data Samples" and "Advanced Data Samples". Currently it list all of the nodes, but what happen if I got like 20+ some examples listed under "Basic Data Samples", that will be list all to the bottom of the webpage....

Thanks in advance!

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, January 20, 2006 4:28 PM by scottgu
Hi David,

Parameters are actually pluggable and extensible. Rather than use a page property, you could easily just do this:

namespace MySamples {
public class TodayParameter : Parameter {
protected override object Evaluate(HttpContext context, Control control) {
return DateTime.Today;
}
}

public class UserNameParameter : Parameter {
protected override object Evaluate(HttpContext context, Control control) {
return User.Identity.Name;
}
}
}

You could then add your

<MySamples:TodayParameter> to the collection.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Saturday, January 21, 2006 12:55 PM by scottgu
Hi Pat,

Glad you like it! :-)

There are two ways to solve the site navigatione expand/collapse structure:

1) The easiest way is to just use the built-in <asp:menu> or <asp:treeview> navigation controls. These allow you to automatically handle multiple levels of hierarchy and expand/collapse on demand. The only reason I didn't use them above was to show off how to build a custom navigation menu instead.

2) If you want to use a custom menu like I did above, you could write some javascript (and/or encpasulate your custom menu inside a user-control to make it more re-usable w/ the javascript). That way you could show/hide the different sub-menus dynamically.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Sunday, January 22, 2006 7:44 AM by David Taylor
Thanks for your tip about extending datasource parameters! I had actually assumed they would have been extensible....I just did not realise how easy it would be :-)

I will definately try using that in one of my projects.

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, February 8, 2006 2:24 AM by scottgu
Hi Geetha,

I believe you should be able to to use the PostBackUrl functionality just fine with master pages. Can you send me an email (scottgu@microsoft.com) with a simple repro of the issue you are running into? I can then help you with it.

Thanks,

Scott

# navication model

Monday, February 13, 2006 3:47 AM by Malarvili
What is a navigation model to a webside. Can you explain me ? Thanks

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, July 28, 2006 12:27 PM by Sevein
Thanks, scottgu, you helped me so much with this article!

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, September 15, 2006 7:03 AM by Richard Cannock
Hi Scott, Ideally, i'd like a top level navigation bar that contains effectively "categories", that then has a left hand side navigation bar that depends on the top level one. Top level nav will be in different html container (i.e. div), than left hand side, so i can't use nested repeaters etc? How would this best be implemented with sitemaps (ideally a sql site map?). Cheers Rich

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Tuesday, September 19, 2006 12:30 AM by ScottGu

Hi Richard,

This blog post describes how to use a SQL Site Map Provider: http://weblogs.asp.net/scottgu/archive/2006/01/11/435108.aspx

The SiteMapDataSource control has several properties that you can set to control where the SiteMap starts in the hierarchy.  These include a ShowStartingNode and StartingNodeOffset properties.  You can use these to help control where your left-hand navigation begins.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, September 22, 2006 8:36 AM by Neel
Scott, I like your article, I am not able to handle a scenario can you help me out here I got the navigation set up using the masterpage and breadcrumb but for some reason, if i use a querystring using response.redirect or server.transfer, I am redirected to the new page, but the bread crumbs are missing I have tried all the ways i know off. Help me out Thank you Neel

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, September 22, 2006 9:04 AM by Richard Cannock
Hi Scott, Thanks for replying. I did use a sql site map provider, two menu controls, and two site map datasources for the top and left navigation menu. Only problem was that i had to hide the left nav on the home page, otherwise the left nav repeats the top menu items! Cheers Richard

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Sunday, September 24, 2006 12:15 PM by ScottGu

Hi Neel,

One thing to check is whether you have multiple entries in the SiteMap for the particular page (with slightly different querystring values).  If you specify one or more items in the SiteMap with querystring values, then the breadcrumb will only show up if you have the same querystring value.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Monday, September 25, 2006 6:01 AM by Dukuly
Hi Scott, Thanks for your great efforts. kind regards Dukuly

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Wednesday, October 11, 2006 12:47 PM by Akber Ali
Well so far it seems that this tutorial is incomplete and the reason is unavailability of the CSS file. Tutorial means what I see, can produce, but this is not the case here.

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Thursday, October 12, 2006 12:00 AM by ScottGu

Hi Akber,

I posted a link to the completed sample above (here it is again: http://www.scottgu.com/BlogPosts/data2/dalwalkthrough.zip)

The .css file to build the sample is included within it.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Saturday, October 28, 2006 12:06 PM by ScottGu

Hi Brett,

Any chance you could send me email with more details about what you are doing?  I can then loop in a few additional folks to see if they can help.

Thanks,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Thursday, November 2, 2006 11:03 AM by ctm
Great job! I've been working with this new sitemap stuff for 3 days, trying to get it to coordinate between 2 different menus, starting at different locations and this is the 1st article I've found that's provided some needed clues. Thanks.

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Monday, November 6, 2006 8:19 AM by mark
Is it possible to make a siteMapNode that only displays text like a label? i.e. If someone clicks on group-header node I don't want anything to happen. Right now I have to put a value into the URL attribute of the sitemap. If I remove the URL attribute from my site map the whole group disappears. i.e. In your example, how would I make "basic data samples" a label only.

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, November 10, 2006 6:05 AM by dominique
Hi Scott, A small question about breadcrumbs. I like them because it is important to see where we are in the navigation and we can easily com back in sequence. Suppose we have: Home > Basic Data Samples > Samples 1. I think it is not logical that "Home >" is displayed because "Home" is at the same level than "Basic Data Samples" or "Advanced Data Samples". Is it possible to have only : Basic Data Samples > Samples 1 ? Cheers, Dominique

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Saturday, November 11, 2006 1:19 PM by ScottGu

Hi Dominique,

The good news is that there is a property on the SiteMapDataSource called "ShowStartingNode".  If you set this to false then the "home" node won't be displayed.

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Sunday, November 19, 2006 4:46 PM by ScottGu

Hi Chris,

You should be able to use the CSS Adapter Toolkit to accomplish this (and highlight one of the links): http://weblogs.asp.net/scottgu/archive/2006/10/28/CSS-Control-Adapters-Update-_2800_Beta3_2900_.aspx

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Tuesday, November 28, 2006 5:51 AM by Nidhi Sharma

Thanks, scottgu, you helped me so much with this article!

# using button images as links with a sitemap

Saturday, December 16, 2006 1:34 PM by Lars

I'd like to know if it's possible to use buttons(different for different links) with my sitemap controlled menu?

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Saturday, December 16, 2006 10:24 PM by ScottGu

Hi Lars,

Yep - you shoudl be able to use a button just fine to accomplish what I did above.  If you are using an image or html button then you'll probably just want to wire-up some client-side JavaScript to navigate to the location you want.

Otherwise, you might just want to put an image within the html <a> element -- that way you can make it look like a button (or anything else you want).

Hope this helps,

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, January 19, 2007 10:37 AM by Jessica

Great article.  Have you run into any problems with MasterPages, SiteMap and the MenuItemClick event?  I have a menu control on a master page using a SiteMap.  The MenuItemClick event isn't getting hit.  If I change the menu control to use menuitems on the page (instead of a SiteMap), the click event is fired.  Have you seen this before?

Thanks for the great example.

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Friday, January 19, 2007 9:03 PM by ScottGu

Hi Jessica,

I haven't heard of this problem.  Are you using the Menu for navigation or postback?

Thanks,

Scott

# Thanks a lot :)

Tuesday, January 30, 2007 11:34 AM by Yogev

You REALLY helped with the title thing.

I was stuck on that for a few days :)!

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Thursday, February 8, 2007 3:51 PM by reji

Hi Scott,

Is there a way we can hide a node in the sitemap file. I have main menu as my root node under which i have home,about, products etc. while using menus i had opted for showstartingnode = "false" but dont know what option do i have with a sitemappath.

Also i get an error after my program is run called a "circular reference error"

would really appreciate your help on this.

thankyou

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Saturday, February 10, 2007 1:56 PM by ScottGu

Hi Reji,

Can you provide some more details on which site map node you are trying to hide?  I'm not entirely sure i understand the scenario.

Thx!

Scott

# re: Data Tutorial #2: Building our Master Page and Site Navigation Structure

Thursday, March 8, 2007 1:59 AM by Raj

Scott,

I'm using menu control for navigation,i want to hide a particular node for particular Page.

Is there any way to do it?