Getting a page's URL in code-behind
While it would be a very nice feature to have in .NET it seems to make sense that there is no method that will generate a URL for you to a page even though we have strongly typed code-behind classes that often times drive the page. Consider that the pages are just ASPX files that can be named anything and can live anywhere in your application structure. They can be derived from any page-derived class in the accessible namespaces (the framework supplied System.Web.UI.Page class, or any class that you create in your application assemblies that was derived from the framework's web page class). This provides us with very flexible design and application structure but as a result we don't have a reliable way to say "give me the URL for X". A solution to this that solves two problems at once is to create a shared/static GetUrl() method on the pages. This method provides the root-relative URL to the page that owns the code-behind class as well as specifying required parameters so you don't have to guess at them or encounter problems later on. Let's take an example of a class that shows the attributes for some item. This page lives at the root of our application: ourApplication/ItemAttributes.aspx Here's the code-behind class:
Public Class ItemAttributes Inherits System.Web.UI.Page ... Public Shared Function GetUrl(itemID As Integer, _ page As System.Web.UI.Page) As String Return page.ResolveUrl("~/ItemAttributes.aspx?itemID=" _ & itemID.ToString) End Function End Class
The GetUrl() method expects a couple of arguments: first an itemID because we need a reference to some item so we know what item's attributes to show; second, an instance of a System.Web.UI.Page class. We need the instance of the page class so we can access the Page.ResolveUrl() method. Now, any other pages in the application can create links to this page by calling the public shared method:
ItemAttributes.GetUrl(12, Me) 'returns "/ourApplication/ItemAttributes.aspx?itemID=12"
A benefit of this technique is that we get a more robust application that is not quite as suceptible to growing pains. Let's say that we move this page because our application is getting bigger and the pages are getting cluttered. We'll move the page to a directory of common pages: ourApplication/common/ItemAttributes.aspx We can just modify the returned string in the GetUrl() method. All the pages that call GetUrl() to use this page link will follow along without a glitch:
Public Shared Function GetUrl(itemID As Integer, _ page As System.Web.UI.Page) As String
Return page.ResolveUrl("~/common/ItemAttributes.aspx?itemID=" _ & itemID.ToString)
Now let's imagine that we have to add another querystring value to the page because we now need to get information about the category that this item is in. When we modify our page to look for the querystring value all the page requests (from other pages) will start failing. We don't know all the places that this page is called in the application so we will have to do some search and replacing as well as a pretty good job testing the application to find the now-broken references. However, there is salvation! All we have to do is change the GetUrl() method signature to expect the new argument and change the returned string structure:
Public Shared Function GetUrl(itemID As Integer, categoryID As Integer, _ page As System.Web.UI.Page) As String Return page.ResolveUrl("~/common/ItemAttributes.aspx?itemID=" _ & itemID.ToString & "&categoryID=" & categoryID.ToString)
Now when we try to the build the application we'll get compile errors everywhere that this method is called. We can go and repair all those broken calls with the confidence. Of course, depending on how you build your pages, you could add an overloaded method that still accepts the original set of arguments and have it call the new method with a default value so you don't have to repair broken calls. This is a great approach if you can build the changed page to function without the additional information. By using this technique you get several advantages: 1. Flexibility to move pages without having to change lots of hard-coded URLs. 2. Compile-time debugging (reduces testing and potential customer discoveries of overlooked runtime bugs) 3. Multi-developer teams don't have to waste precious time researching what the page expects for a querystring because the calls have strongly typed arguments with descriptive names.
Where to Next?
Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article.
Links in this Document
Talk Back! Comment on Imar.Spaanjaars.Com
I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.
When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.
If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the Doc ID of the document.
Please correct the following errors:
Unfortunately, something went wrong and your message or comments have not been submitted successfully.
There's a fair chance things broke down because you tried to post something that looks like HTML. Things that look like HTML include (X)HTML, obviously, XML, ASP.NET markup and c# generics syntax as all of them use the < and > characters.
If that's the case, try altering your message and remove anything that looks like an angled bracket. You can replace them with [ and ] for example so you can still make it look like HTML to some extend.
If, on the other hand, you were trying to spam this web site, I am pretty glad I caught you in the act and stopped you from doing so ;-)
Also, please don't use links in your posts; I had to block them to filter out most of the junk mail I am receiving.