Root and Virtual: path tip

Well I think I figured out a very simple way to make my paths working in my virtual directory and in the root of the live server.

The problem as I mentioned this morning, was about URL rewriting.

So if you have a fake URL like this : http://mysite/products/ you are surely going to have some problems with your images.

Indeed if you don't do anything your images are now seen under http://mysite/products/images/yourimage

This can be a nightmare if you develop locally on Windows XP (as everybody should do :-)) under a virtual directory. As I said this morning the ~ to indicate the root for a server side tag doesn't work anymore for this scenario.

Scott  suggested a BASE tag but the cons there is about implementing this in every page and changing agin when I deploy the site.

Another solution I just found is to write my images path like this:

~//images/myimage.gif (note the double /) and it works perfectly using a virtual directory or not.

I should also mention the idea submitted by Jeff Gonzalez (thanks for that) about the stylesheets links:

We wrote a config section for our stylesheets that allows them to be configured dynamically via the configuration API. In our PageBase class we use the ~ in our paths.

The config file xml looks like....

<StyleSheetSettings>
<StyleSheet Name="DefaultPage" Href="~/Lib/Css/DefaultPage.css" Media="Screen"/>
</StyleSheetSettings>

In our PageBase class we have the following code in our Init method... (forgive me, it is VB.NET)

Dim _StyleSheets As StyleSheetCollection = CType(System.Configuration.ConfigurationSettings.GetConfig("StyleSheetSettings"), CodeMakerX.Foundation.Web.Helpers.StyleSheetSettings).StyleSheets
For i As Int32 = 0 To _StyleSheets.Count - 1
Page.Controls.AddAt(0, _StyleSheets(i).Render)
Next

The render method for the StyleSheet class returns a LiteralControl built using a stringbuilder...

_sb = new StringBuilder();

_sb.Append(Environment.NewLine);
_sb.Append("<link media=\"\"").Append(Media).Append("\"\" ");
_sb.Append("href=\"\").Append(_StylePath).Append(Href).Append(\"\" ");
_sb.Append("type=\"text/css\" rel=\"stylesheet\">");
_sb.Append(Environment.NewLine);

return new LiteralControl(_sb.ToString());

Inside our Href property get statement, we have the following code to ensure that the path resolves correctly regardless of using virtual directories or having the application reside in the root...

if( _Href.IndexOf("~") == 0 )
{
if (System.Web.HttpContext.Current.Request.ApplicationPath == "/" )
{
_Href = _Href.Replace("~", "");
}
else
{
_Href = _Href.Replace("~", System.Web.HttpContext.Current.Request.ApplicationPath);
}
}

return _Href

So far we have been able to run all of our web applications on our local machines using vdirs for development, and run them as the root on staging and production.

 

2 Comments

  • The Page.ResolveUrl(string relativeUrl) method takes into account if you are using '~' in the relative url. Seems like that 'if' statement could have used that instead?



    I always use this to resolve url's server side so i don't have any problems with virtual directories.

  • Unfortunatelly Page.ResolveUrl will return relative Urls, relative to the path where the page is. Which is not the same Url the client sees if you use url rewriting, so the relative paths are off, as Paschal says.



    There's a function to resolve ~/ paths to absolute paths in the System.Web.Util namespace, but since it's not documented I ended up creating my own utility function that will resolve application relative urls (~/) to web server absolute paths.



    string ResolveUrl(string AppRelativePath)

    {

    if( AppRelativePath == null || !AppRelativePath.StartsWith(&quot;~/&quot;) )

    {

    return AppRelativePath;

    }



    StringBuilder AbsolutePath = new StringBuilder(HttpRuntime.AppDomainAppVirtualPath);



    if( AbsolutePath[AbsolutePath.Length - 1] != '/' )

    {

    AbsolutePath.Append('/');

    }



    AbsolutePath.Append(AppRelativePath, 2, Name.Length - 2);



    return AbsolutePath.ToString();

    }

Comments have been disabled for this content.