Fabrice's weblog

Tools and Source

News

My .NET Toolbox
An error occured. See the script errors signaled by your web browser.
No tools selected yet
.NET tools by SharpToolbox.com

Read sample chapters or buy LINQ in Action now!
Our LINQ book is also available on AMAZON

.NET jobs

Emplois .NET

Tuneo

ASP.NET Hosting transatlantys

Contact

Me

Others

Selected content

Archives

URL rewriting breaks ASP.NET 2's themes

If you try to use URL rewriting and ASP.NET 2 themes at the same time, you will likely get broken pages, because the two don't mix very well.
A typical link to a theme's stylesheet looks like this in the generated HTML:
<link href="App_Themes/Theme1/StyleSheet.css" type="text/css" rel="stylesheet" />
The problem is that these links to CSS documents are using relative paths, which is not going to work fine if you use RewritePath on your web requests.

Update: as Scott and Wilco wrote in comments, a much simpler solution is to use the new overload of the RewritePath method that takes one additional parameter named "rebaseClientPath".

Thomas Bandt has a solution, described in German (the source is available), that relies on response filters.
Here is another solution I use. It consists on overriding the Render method in a base page or in a master page:

protected override void Render(HtmlTextWriter writer)
{
  foreach (Control control in Page.Header.Controls)
  {
    HtmlLink  link;

    link = control as HtmlLink;
    if ((link != null) && link.Href.StartsWith("~/"))
    {
      if (Request.ApplicationPath == "/")
        link.Href = link.Href.Substring(1);
      else
        link.Href = Request.ApplicationPath+"/"+link.Href.Substring("~/".Length);
    }
  }
  base.Render(writer);
}

Comments

Scott said:

Fabrice,

I remember a similar issue on a project using one of the early 2.0 builds.

There is a new overload for ReWritePath which seemed to fix my issue. I will have to dig through some old notes to remember what it was, but it may be worth a shot.

I remember my change was to set the second paramter of HttpContext.RewritePath (String, Boolean) to false.

-Scott
# January 11, 2006 1:19 AM

Fabrice said:

Great! That's much better.
It would have been surprising if the ASP.NET team did not provide a solution for this.
# January 11, 2006 4:54 AM

Tim said:

Hey guys, I added the line to the code: app.Context.RewritePath(destinationUrl, false); but the themes still does not load :( Any help?
# October 18, 2006 9:20 PM

Tim said:

Actually my mistake, it does load with one exception if you add an ending "/" to the url, it will break the theme. For example, www.domain.com/tim will work but www.domain.com/tim/ will load the correct page, but the themes are missing. The path to the CSS file is missing an extra "../" to find the correct location Any ideas?
# October 19, 2006 6:28 PM

Fabrice Marguerie said:

Tim, I had the same problem. What I do to resolve this is to do a (permanent) redirection to URLs without the ending "/".

Here is the regular expression I use: ^(.*)/(\?.*)?$

I redirect to: $1$2

You can notice that this expression also supports URLs with parameters.

# October 19, 2006 8:23 PM

Yisman said:

Hi Fabrice,

i have a similar problem, though i am not using rediredtion.

i am trying to override a page's render method and send the html string via email.

though, i have easily succeeded in getting the html sting like this:

       Dim aStringBuilder As StringBuilder = New StringBuilder

       Dim strWriter As IO.StringWriter = New IO.StringWriter(aStringBuilder)

       Dim aHtmlTextWriter As HtmlTextWriter = New HtmlTextWriter(strWriter)

       MyBase.Render(aHtmlTextWriter)

       Dim st As String = aStringBuilder.ToString

       SendMail(st)

SendMail is my own mailing function. the problem is that the rendered HTML disregards the theme i have set for this page. any ideas? i'm really scouring the net on this one. thanks.

# December 11, 2006 12:31 PM

Bryce said:

Cheers, solved my problem, great work.

# March 20, 2007 6:31 PM

Gabriel said:

Where does the HttpContext.RewritePath line go?  How does it know to only modify the them path, or does it modify all paths?

# May 16, 2007 5:56 PM

johny.cz said:

hi, i had problem with images in web controls with skinid. I solved it with this simple redirection int application_beginreguest :

Dim appt = "App_Themes"

If url.Contains(appt) And Not url.StartsWith("/" & appt) Then

Response.Redirect("/" & url.Substring(url.IndexOf(appt)))

End If

# April 24, 2008 3:50 AM

veerukk said:

hi , i had problem with loading image & .js files after changing the url. plz anybody can help me if u come across this problem.

# June 23, 2008 10:16 PM

pratikmehta921985 said:

Many many thanks, this working like charm. i stucked with this problem. you are my hero............. thanks again.

# November 26, 2008 2:41 AM

Franz43 said:

Solved my problem using Page.ResolveUrl("~/someurl") for the relative path in the master page.

# December 29, 2009 7:23 PM