Click here to Skip to main content
13,300,002 members (61,841 online)
Click here to Skip to main content
Add your own
alternative version


9 bookmarked
Posted 14 Apr 2009

Using an Extension Method to Strongly Type Your Navigation

, 14 Apr 2009
Rate this:
Please Sign up or sign in to vote.
Hot to use an extension method to strongly type your navigation

After writing a very large web-based application with lots of pages, I realized that I was falling into a trap.

Magic strings were going to be the death of me!

If you are not familiar with what a "magic string" is, it is really any type of string in your application that is not strongly typed somehow. For example, if you write a paragraph like this:

lblParagraph.Text = "<p>This is a paragraph."; 

you have a lot of string magic going on! You probably would want to refactor that to have a strongly typed object that implies you are dealing with a paragraph, and then refer to the text based on its source, whether it's a constant, resource, or another way to inject the information without making it magically reside in the code.

So, what is a common pattern in our website (this is addressed in MVC, by the way, I'm talking the old WebForms engine)?


This seems fine until you end up refactoring the page or splitting it up, etc. Isn't there a better way?

My first step was to start to use constants like this:

const string NAVIGATE_SOME_PAGE = "~/Some/Page.aspx"; 

This was a little more satisfying, until I realized that I was dotting my entire application with multiple "NAVIGATE_SOME_PAGE" references. I could have hacked it by referencing them publicly, but was that really the right way?

Fortunately, our application follows strict naming conventions including adhering to proper namespace use. We don't create a folder called "foo" and then stick an entity in that folder into the namespace "bar".

So, I decided to come up with an extension method. Why an extension method? Because, I couldn't think of some dummy utility class to paste then on when it really is a function of the "Page" knowing where "it" is. So, I extended the page, and did this:

/// <summary>
/// Contains extension methods for System.Web.UI.Page
/// </summary>
public static class PageExtensions
   /// <summary>
   ///     Gets the redirect url based on type
   /// </summary>
   /// <typeparam name="T">The type of the page</typeparam>
   /// <returns>The path to the page</returns>
   public static string GetRedirect<T>(this System.Web.UI.Page page) 
                        where T : BaseController
       const string ROOT_NAMESPACE = "MyNamespace.Web";

       string str = typeof(T).FullName;

       // remove the prefix 
       str = str.Replace(ROOT_NAMESPACE, "~");

       // build the path
       str = str.Replace(".", "/");

       // append the suffix 
       str += ".aspx";

       return str;

Note: This implies you inherit your pages from BaseController... you could just as easily make it System.Web.UI.Page.

Now, when I want to redirect, I do this:


And, the best part? If I delete the page, my compiler throws errors. If I refactor the page, all of the redirects will get refactored with it.

(I realize hacking the namespace to make a path doesn't seem the most elegant solution, but it's the best I could come up with... I'm very open to other ideas on how to tackle this).


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Jeremy Likness
Instructor / Trainer Microsoft
United States United States
Note: articles posted here are independently written and do not represent endorsements nor reflect the views of my employer.

Jeremy Likness is a Cloud Developer Advocate for Azure at Microsoft. Jeremy has spent two decades building enterprise software with a focus on line of business web applications. Jeremy is the author of several highly acclaimed technical books including Designing Silverlight Business Applications and Programming the Windows Runtime by Example. He has given hundreds of technical presentations during his career as a professional developer. In his free time, Jeremy likes to CrossFit, hike, and maintain a 100% plant-based diet.

Jeremy's roles as business owner, technology executive and hands-on developer provided unique opportunities to directly impact the bottom line of multiple businesses by helping them grow and increase their organizational capacity while improving operational efficiency. He has worked with several initially small companies like Manhattan Associates and AirWatch before they grew large and experienced their transition from good to great while helping direct vision and strategy to embrace changing technology and markets. Jeremy is capable of quickly adapting to new paradigms and helps technology teams endure change by providing strong leadership, working with team members “in the trenches” and mentoring them in the soft skills that are key for engineers to bridge the gap between business and technology.

You may also be interested in...


Comments and Discussions

GeneralMy vote of 5 Pin
zenwalker198528-Jun-11 18:40
memberzenwalker198528-Jun-11 18:40 
AnswerAn alternative way to do this that also gives you strongly typed page parameters Pin
HightechRider14-Apr-09 17:36
memberHightechRider14-Apr-09 17:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171207.1 | Last Updated 14 Apr 2009
Article Copyright 2009 by Jeremy Likness
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid