ASP.NET Hosting

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);
}

12 Comments

  • 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

  • Great! That's much better.

    It would have been surprising if the ASP.NET team did not provide a solution for this.

  • Hey guys,

    I added the line to the code:

    app.Context.RewritePath(destinationUrl, false);

    but the themes still does not load :(

    Any help?

  • 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?

  • 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.

  • 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.

  • Cheers, solved my problem, great work.

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

  • 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

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

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

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

Comments have been disabled for this content.