Navigation Hyperlink and Data Expression


Thus far, creating URLs for Hyperlinks has been done programmatically. Examples of some problems this can cause:
  1. Messy business methods – business methods should not have to return URLs
  2. Loss of StateContext Data – creating a URL too early in the page life cycle will cause subsequent changes to StateContext Data to be ignored and hence not remembered by the Crumb Trail
To remedy this the Navigation Framework has a NavigationHyperLink control which can be used for all types of Navigation, i.e., forward, backward and refresh. The following table explains the Navigational properties of the control.
Navigational properties of the NavigationHyperLink
Property Purpose
Direction Indicates the type of Navigation, i.e., Forward, Back or Refresh
ToData The NavigationData to be passed. This is only relevant for forward or refresh Navigation
IncludeCurrentData Indicates whether to include the StateContext Data together with the ToData. This is only relevant for forward or refresh Navigation
Action Child Transition or Dialog key. This is only relevant for forward Navigation
Distance The number of Crumbs to go back. This is only relevant for backward Navigation

ASP.NET expressions are a declarative way to set control properties based on information that is evaluated at run time. There is a NavigationData Expression that can be used to set the ToData of a Navigation HyperLink. If the Navigation framework was installed manually in the Getting Started section, the Expression must first be registered under the compilation section of the Web.config as shown below (a NuGet installation automatically adds this configuration).

<compilation debug="true" targetFramework="4.5">
	<expressionBuilders>
		<add expressionPrefix="NavigationData" type="Navigation.NavigationDataExpressionBuilder, Navigation"/>
	</expressionBuilders>
</compilation>
The syntax to use it is <%$ NavigationData: Key1?type1=Value1, Key2?type2=Value2 %>. The valid type values are string, bool, int, long, float, double, decimal, datetime, byte and char, with the default being string. An example of its use to pass String and Int32 values is shown below.

<cc1:NavigationHyperLink ID="NavigationHyperLink1" runat="server" Action="D1" ToData="<%$ NavigationData: title=Mr, age?int=18 %>" />

Sample Web Site

The NavigationHyperLink means it is not necessary to return the Link property from the Search method because the URL can be built in the Design view. Therefore, the Search method can be changed to return IEnumerable<Person> and the anonymous type creation can be removed as shown below.

public IEnumerable<Person> Search(
	[NavigationData] string name, 
	[NavigationData] string minDateOfBirth, 
	[NavigationData] string sortExpression,
	[NavigationData] int? startRowIndex,
	[NavigationData] int? maximumRows)
{
	var q = from p in _People
			where (name == null || p.Name.ToUpperInvariant().Contains(name.ToUpperInvariant()))
			&& (minDateOfBirth == null || p.DateOfBirth >= DateTime.Parse(minDateOfBirth))
			select p;
	if (sortExpression != null)
		q = !sortExpression.EndsWith("DESC") ? q.OrderBy(p => p.Name) : q.OrderByDescending(p => p.Name);
	StateContext.Data["totalRowCount"] = q.Count();
	return q.Skip(startRowIndex ?? 0).Take(maximumRows ?? 10);
}
Now that the anonymous type has been removed from the Search method, strongly-typed DataBinding can be used by setting the ItemType of the GridView, see Figure 65.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" ItemType="NavigationSample.Person" SelectMethod="Search" OnCallingDataMethods="GridView1_CallingDataMethods">
In Listing.aspx replace the HyperLink control with a NavigationHyperLink control, setting the Action property to the Select Transition and the ToData to pass the id of the selected Person as shown below.

<ItemTemplate>
	<cc1:NavigationHyperLink ID="NavigationHyperLink1" runat="server" Action="Select" ToData='<%# new NavigationData(){{ "id" , Item.Id }} %>' Text='<%#: Item.Name %>' />
</ItemTemplate>
Pressing F5 will display the Person List with a hyperlink to the Details working as before.

In Details.aspx remove the ListView and associated CrumbTrailDataSource controls and replace with a NavigationHyperLink control as shown below, setting the Navigation Direction to Back and the Distance to 1.

<cc1:NavigationHyperLink ID="HyperLink1" runat="server" Direction="Back" Distance="1" Text="Person Search" />
Pressing F5 and selecting a person will show the link back to the Listing working as before, retaining all the search criteria, sorting and paging information.

Add two NavigationHyperLinks to the Listing.aspx just before the GridView as shown below. This uses refresh Navigation to pass a hard-coded page size and reset the page number (if the Navigation framework was not NuGet installed, register the NavigationDataExpressionBuilder in the Web.config). Pressing F5 and clicking these links will toggle the number of rows displayed.

Page size 
<cc1:NavigationHyperLink ID="HyperLink1" runat="server" Direction="Refresh" ToData="<%$ NavigationData: startRowIndex?int=0,maximumRows?int=5 %>" Text="5" />
<cc1:NavigationHyperLink ID="HyperLink2" runat="server" Direction="Refresh" ToData="<%$ NavigationData: startRowIndex?int=0,maximumRows?int=10 %>" Text="10" />
However, changing the page size causes any search criteria, page number and sort order to be lost. This information is available as it's held in the StateContext Data. To ensure this current data is passed together with new page size set the IncludeCurrentData property to true as show below.

<cc1:NavigationHyperLink ID="HyperLink1" runat="server" Direction="Refresh" ToData="<%$ NavigationData: startRowIndex?int=0,maximumRows?int=5 %>" Text="5" IncludeCurrentData="true" />
<cc1:NavigationHyperLink ID="HyperLink2" runat="server" Direction="Refresh" ToData="<%$ NavigationData: startRowIndex?int=0,maximumRows?int=10 %>" Text="10" IncludeCurrentData="true" />
Pressing F5 shows the search criteria, page number and sort order are retained when changing page size. Also, the link back from the Details to the Listing remembers the page size selected.

Last edited Aug 4, 2013 at 7:28 PM by GrahamMendick, version 3