Different approaches for resolving URLs in ASP.NET

There are various ways that are available in ASP.NET that we can use to resolve relative paths to a resource on the server-side and making it available on the client-side. I know of 4 ways -

1) Request.ApplicationPath
2) System.Web.VirtualPathUtility
3) Page.ResolveUrl
4) Page.ResolveClientUrl

To show the difference, let's take an example. Let's say our application has 2 folders, with the following files -

/Forms1/forml.aspx
/Forms2/form2.aspx
form1.aspx redirects to form2.aspx and needs to get the path to that file.

We will consider 2 case -
a.) When application is hosted in a virtual directory
http://www.server.com/virtual-directory/Forms2/form2.aspx
b.) When application is not in a sub-directory
http://www.server.com/Forms2/form2.aspx

1) Request.ApplicationPath
The most common way people use this method is by concatenating strings to create the Url to a resource.
sUrl = Request.ApplicationPath + "/Forms2/form2.aspx";
In case a), Request.ApplicationPath will return "/virtual-directory". Notice there is no slash at the end, and the above sUrl gets a value
/vitural-directory/Forms2/form2.aspx
In case b). Request.ApplicationPath will return "/". Notice there is a now a slash at the end, and sUrl gets a value
//Forms2/form2.aspx
In this case, rather than requesting "http://www.server.com/Forms2/form2.aspx", the browser requests "http://Forms2/form2.aspx".

So, don't use Request.ApplicationPath to get relative paths to files.


2) Page.ResolveClientUrl
sUrl = Page.ResolveClientUrl("~/Forms2/form2.aspx"); 

This will result in -
"../Forms2/form2.aspx"
Notice that the path returned is relative to the calling page.


3) Page.ResolveUrl
sUrl = Page.ResolveUrl("~/Forms2/form2.aspx"); 

This will result in -
"/Forms2/form2.aspx"
Notice that the path returned in this case is relative to the site root, ie, from the top of the virtual directory.

So which one is better between ResolveClientUrl and ResolveUrl? I don't think one is better than the other, but most people use Page.ResolveUrl.


4) System.Web.VirtualPathUtility
sUrl = VirtualPathUtility.ToAbsolute("~/Forms2/form2.aspx");

This will resolve, same as Page.ResolveUrl, to
"/Forms2/form2.aspx"

Whats the diffirence between VirtualPathUtility and ResolveUrl? Well, there are a few -

  • ResolveUrl can only be called in the context of a Page. But VirtualPathUtility can be used from anywhere.

  • VirtualPathUtility will throw an error if there are Query String parameters in the URL -
    // throws error
    sUrl = VirtualPathUtility.ToAbsolute("~/Forms2/form2.aspx?q=123");

    // works as expected
    sUrl = Page.ResolveUrl("~/Forms2/form2.aspx?q=123");

To conclude, I think Page.ResolveUrl should be used anytime you are in the context of the Page. Everywhere else, use VirtualPathUtility.

2 comments:

Claudio Friederich said...

One important difference between Page.ResolveUrl and Page.ResolveClientUrl is design time behavior. When passed a path containing a ~, ResolveUrl will, at design time, leave the path unchanged (as it is already site relative). At run time, it will do the same thing, but it will resolve the ~. Why is this important? If you build a custom web control, and you use ResolveUrl, the control will not display correctly at design time if you use a ~, but it will work at run time. The designer will ignore client-side urls that have ~ in them. Whereas ResolveClientUrl, by definition, resolves the ~ in all cases to make it page relative. Thus the control will display correctly in all modes if you use ResolveClientUrl. Note that if you do ildasm on the Image WebControl for example, it also uses ResolveClientUrl for the same reason.

Aditya Bokade - The Corporate Trainer. said...

Hi Rohit,
Thank you very much for making the things to understand so well, so easily.
I was breaking my head since many hours and you made my day!
God bless you.

Post a Comment

I am a programmer based in Seattle, WA. This is a space where I put notes from my programming experience, reading and training. To browse the list of all articles on this site please go here. You can contact me at rohit@rohit.cc.