views:

1539

answers:

8

I'm using the urlrewriter.net as recommended in several questions in here. I'm having difficulties with displaying images and with the stylesheet.

I read ScottGu's Blog (again as recommended in here) and in the end he does reffer to this problem and states to use ~/ for server controls etc. ("Handling CSS and Image Reference Correctly" at the end of the article).

I tried his solution and it doesn't seem to work.

The only thing that seems to work for me is to write the full path. For some reason, it doesn't seem to me as the right solution. It would make a serious problem developing and debugging.

Does anyone know what can be the cause of the problem? Is there something I need to change in the web.config file?

Thanks

A: 

I think you need to exclude your stylesheets and image directories from the rewrite engine. I am not familiar with the engine you are using, but if you are using a rewrite rule that rewrites based on a very wide rule, it will incorrectly point to your stylesheets and images, and javascripts I believe.

You could also experiment with the base tag.

<base href="http://www.w3schools.com/images/" />

Try placing it in your <head>, pointing to your images folder.

Jamie
A: 

I second using the base href. Though you do have to do a bit of fudge down to the difference when the site is running from the root of the domain i.e. production compared to the visual studio server.

<base id="BasePath" runat="Server"/>

then in master code behind.

protected void SetBaseHref() {
if (Request.RawUrl != Request.Url.PathAndQuery)
{
string baseUrl = "";

        if (Request.IsSecureConnection)
            baseUrl += "https://";
        else
            baseUrl += "http://";
        baseUrl += Request.Url.Host;

        if (Request.Url.Port != 80)
            baseUrl += ":" + Request.Url.Port.ToString();

        baseUrl += Request.RawUrl;

        BasePath.Attributes.Add("HREF", baseUrl);
    }

}

+1  A: 

In my experience the base tag is the source of far more problems than it solves

I strongly suggest the first option, of limiting what the URLrewriter is allowed to effect by i.e. checking for .aspx extension before acting.

annakata
A: 

~/ will only work for tags that have runat="server" attributes, because this tells asp.net to render the control.

e.g.

<link href="~/mycss.css" type="text/css" rel="stylesheet" />

will not render how you expect because asp.net is not rendering the control. Instead you should use.

<link runat="server" href="~/mycss.css" type="text/css" rel="stylesheet" />

Alternativly place the css link in the head tag e.g.

<head runat="server">
  <link href="~/mycss.css" type="text/css" rel="stylesheet" />
</head>

Ady
A: 

Have you tried with Page.ResolveUrl?

<link href="<%=Page.ResolveUrl("~/mycss.css")%>" type="text/css" rel="stylesheet" />
Eduardo Molteni
A: 

You can use this:

<a href="<% =GetBaseURL() %>/">Home</a>

public static string GetBaseURL()
{

string url =HttpContext.Current.Request.Url.Scheme + “://” + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.ApplicationPath.TrimEnd(’/') + ‘/’;

//EPiServer’s url start with a / so remove the url if (when) it contains one
if(url.EndsWith(”/”))
return url.Remove(url.LastIndexOf(”/”));
else
return url;
}
A: 

A big problem with URL rewriting is that it screws you when you use relative paths.

For example, if you have a file in the root of you application called page.aspx which is used for pages at multiple levels of navigation. e.g.

Virtual Path    =>    Physical Path
 /              =>    /page.aspx?id=1
 /food/banana   =>    /page.aspx?id=2

Let's say you had a relative path in page.aspx to your css file witch lives at /css/main.css

<link rel="stylesheet" href="css/main.css"/>

When page.aspx is executed from the context of /food/banana, the browser will try to look for /food/css/main.css, which doesn't exist.

The way I go about it, is to dissable URL rewriting for images, CSS, JS and have an absolute link to your stylesheet (and img src and JavaScript). This way you can guarantee that the browser will always find it. Then from your stylesheet you can use relative paths for the background images.

I've found that this method is the simplest to maintain as you don't spend weeks trying the reverse-re-write your links.

Greg B
A: 

I had an issue with stylesheets and images as well.

I did not want to use the Base Href solution and fixed my problem with updating my relative paths to begin with a single slash.

My Setup

nopCommerceStore is used to build a webshop.

nopCommerce uses the 'UrlRewritingNet.UrlRewrite' library to handle url rewriting.

nopCommerce uses the ASP.NET Themes and Skins for defining the apearance of the webshop.

On the server side you have the following folder structure:

root

root/App_Themes/darkOrange/base.css

root/App_Themes/darkOrange/cart-checkout-order.css

root/App_Themes/darkOrange/category.css

root/App_Themes/darkOrange/css/ie6.css (this file was eventually removed)

root/App_Themes/darkOrange/img/transparent_image_example.png

root/css/ie6.css

root/MasterPages/Root.Master

root/Default.aspx root/Category.aspx

When landing on the default page (browser requests http;//yourstore/default.aspx) your html source will contain the following html code:

<link href="App_Themes/darkOrange/base.css" type="text/css" rel="stylesheet" />
<link href="App_Themes/darkOrange/cart-checkout-order.css" type="text/css" rel="stylesheet" />
<link href="App_Themes/darkOrange/category.css" type="text/css" rel="stylesheet" />
...

The browser will fire the following requests:

http;//yourstore/App_Themes/darkOrange/base.css

http;//yourstore/App_Themes/darkOrange/cart-checkout-order.css

http;//yourstore/App_Themes/darkOrange/category.css

...

When clicking on the category 'Books', the browser requests http;//yourstore/Category/29-books.aspx) your html source will contain the following html code:

<link href="../App_Themes/darkOrange/base.css" type="text/css" rel="stylesheet" />
<link href="../App_Themes/darkOrange/cart-checkout-order.css" type="text/css" rel="stylesheet" />
<link href="../App_Themes/darkOrange/category.css" type="text/css" rel="stylesheet" />

The browser will fire the following requests:

http;//yourstore/Category/../App_Themes/darkOrange/base.css

http;//yourstore/Category/../App_Themes/darkOrange/cart-checkout-order.css

http;//yourstore/Category/../App_Themes/darkOrange/category.css

Transparent PNG in IE6

So far everything runs fine. To make the appearance consistant across all browsers a IE6 specific stylesheet needed to be loaded. I learned two important things:

  1. Do not add the stylesheet to the 'App_Themes' folder but place it in a separate folder.

  2. If referencing images, use relative paths that begin with a single slash.

Stylesheets and the 'App_Themes' folder:

To apply a specific layout to pages that are viewed in IE6, I created a new stylesheet and placed it in the 'root/App_Themes/darkOrange/css' folder. In the file 'root/MasterPages/Root.Master' I added the following lines of html code:

<!--[if IE 6]>
<link rel="stylesheet" type="text/css" media="screen" href="/css/ie6.css" />
<![endif]-->

When a Css file is placed in the 'App_Themes folder or in a subfolder within 'App_Themes' it will automatically be referenced. This caused undesired behavior in non-IE6 browsers. The IE6 layout was applied to the page and messed up the appearance of the page.

When landing on the default page (browser requests http;//yourstore/default.aspx) the server will parse the request. The resulting html source will contain the following html code:

<!--[if IE 6]>
<link rel="stylesheet" type="text/css" media="screen" href="/css/ie6.css" />
<![endif]-->

But also the html contains the following line:

<link href="App_Themes/darkOrange/css/ie6.css" type="text/css" rel="stylesheet" />

All browsers will fire the following request:

http;//yourstore/App_Themes/darkOrange/css/ie6.css

IE6 will fire an extra request (file will be retrieved from the IE cache):

http;//yourstore/App_Themes/darkOrange/css/ie6.css

This was undesired behaviour so I had to replace the 'ie6.css' file to a new folder. It is now placed in 'root/css/ie6.css'.

Referencing images, Url rewriting and relative paths:

To support transparent png images in IE6, the ie6.css file contains some css 'filter' properties.

e.g. One of the div selectors would include the following line of css code:

filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true', sizingMethod='crop', src='../App_Themes/darkOrange/img/transparent_image_example.png');

When landing on the default page (browser requests http;//yourstore/default.aspx) IE6 would request:

http;//yourstore/img/transparent_image_example.png

When clicking on the category 'Books', the browser requests http;//yourstore/Category/29-books.aspx) IE6 would request:

http;//yourstore/img/transparent_image_example.png

Both resulting in 'The page cannot be found' (HTTP/1.1 404 Not Found).

After replacing:

'../App_Themes/darkOrange/img/transparent_image_example.png'

With:

'/App_Themes/darkOrange/img/transparent_image_example.png'

Everything worked fine.

This is because the relative path begins with a single slash. The browser will interpret the url in the following way:

Does it start with 'http;//'? If yes, it must be an absolute path; If no, it must be a relative path.

Relative paths:

Does it start with a single slash? If yes, it must be a 'absolute-path reference'; If no, it must be a 'relative-path reference'

note: see Section 5 'Relative URI References', in the document "Uniform Resource Identifiers (URI): Generic Syntax" (http://www.ietf.org/rfc/rfc2396.txt).

In case of url rewritten pages:

The browser will fail when using 'relative-path references' (e.g. 'http;//yourstore/Category/29-books.aspx' and '../App_Themes/darkOrange/img/transparent_image_example.png').

The browser will succeed when using 'absolute-path references' (e.g. 'http;//yourstore/Category/29-books.aspx' and '/App_Themes/darkOrange/img/transparent_image_example.png').

mathijsuitmegen