Scott on Writing

Musings on technical writing...

URL Rewriting, the Image Web Control, and ~

Recently Scott McCulloch found that when using URL rewriting technique in ASP.NET 1.x I discussed in URL Rewriting in ASP.NET, Image Web controls with the ~ in the ImageUrl property don't resolve correctly.  Specifically, if you have an example of an actual page of, say, /RewriterTester/ListProductsByCategory.aspx?CategoryID=1 that has a “friendly URL” of /RewriterTester/Products/Beverages.aspx, and that page includes an Image Web control with an ImageUrl like ~/images/Logo.gif (meaning there's a file /RewriterTester/images/Logo.gif), then when visiting /RewriterTester/ListProductsByCategory.aspx?CategoryID=1 the image is displayed correctly, but visiting the “friendly URL” results in a broken image.  (Whew, what a mouthful!)  To further complicate things, if you use the ResolveUrl() method, it just works.  That is, if on the page you display the output of ResolveUrl(”~/images/Logo.gif”), the correct URL is displayed, regardless if you visit the actual URL or the friendly URL.

After some serious head scratching and digging through the Base Class Library code with Reflector, I found the problem.  When the Image Web control is rendered, its src attribute is formulated by calling the Control class's ResolveClientUrl() method.  ResolveClientUrl() method is similar to the standard ResolveUrl() method (which works, remember), except for one important fact: it creates relative paths rather than absolute paths.  So, ResolveUrl() gives us something like /RewriterTester/images/Logo.gif, but what ResolveClientUrl() gives us is images/Logo.gif.  Since the path rewriting has occurred long before the Image Web control is rendered, the Image Web control - regardless of whether or not the person is visiting the friendly URL or not - thinks its path is /RewriterTester/ListProductsByCategory.aspx.  So, when it resolves ~/images/Logo.gif, it says, “Ok, well ~/images/Logo.gif is really /RewriterTester/images/Logo.gif, but the relative path for that is just images/Logo.gif,” so it returns just this.  This works great when visiting the actual URL, but when visiting the friendly URL, the browser gets the <img> tag with the src of images/Logo.gif.  Since the browser has visited /RewriterTester/Products/Beverages.aspx, it requests the image at /RewriterTester/Products/images/Logo.gif.  And that, in a nutshell, is the problem.

So what's the solution?  Well, I can think of one simple solution: don't specify the ImageUrl for the Image tag in the declarative syntax.  Rather, specify it in the Page_Load event handler like so:

if (!Page.IsPostBack)
  ImageID.ImageUrl = Page.ResolveUrl(”~/images/Logo.gif”)

This will work since ResolveUrl() gets the absolute path to the file, not the relative path like ResolveClientUrl().  This answer, for me, lead into another question: why does ASP.NET need two methods for resolving URLs?  That is, why have ResolveClientUrl() at all (which is internal, by the way, meaning you can't call it directly - only classes in same assembly can).  Looking at the Callee Graph in Reflector, the following methods call ResolveClientUrl():

  • HyperLink.AddAttributesToRender()
  • HyperLink.RenderContents()
  • Image.AddAttributesToRender()
  • Panel.AddAttributesToRender()
  • TableStyle.AddAttributesToRender()
  • HtmlControl.PreProcessRelativeReferenceAttribute()

I guess I'm missing why a relative path is ever needed.  Won't an absolute path always do the trick?  And if relative paths might be needed, why make ResolveClientUrl() internal?  Why not make it public like ResolveUrl()?

posted on Wednesday, September 29, 2004 9:20 AM

Feedback

# re: URL Rewriting, the Image Web Control, and ~ 10/1/2004 7:04 AM Milan Negovan

Will we see "Scott's Url Package and More" any time soon? :)

# re: URL Rewriting, the Image Web Control, and ~ 10/1/2004 8:11 AM Scott Mitchell

Hehe, it's called ASP.NET 2.0! :-)

# DotNetNuke 2.2 and URL Rewriting 10/3/2004 8:13 PM Chris Hammond's homepage

# re: URL Rewriting, the Image Web Control, and ~ 10/8/2004 5:20 PM Ben Ursu

Would a html base tag on Default.aspx help?

I posted a work-in-progess solution at:
http://lucaslabs.net/blogs/mccullochs/archive/2004/09/28/1061.aspx

# Images And Url Rewriting 11/11/2004 10:04 PM Joel Ross

# re: URL Rewriting, the Image Web Control, and ~ 5/16/2006 5:52 PM Michael Freidgeim

Does the issue applicable for ASP.NET 2.0?
At least ResolveClientUrl() is now public.

# re: URL Rewriting, the Image Web Control, and ~ 7/11/2006 10:14 AM Jamie Crutchley

This is probably old news, but in case people like me are finding this in a search, I thought I'd post some updated info. As of ASP.NET 2.0, if using RewritePath(path, false), this problem goes away for most image controls. However, the HyperLink control will still break if using the ImageUrl attribute. An easy fix is to just next an Image control inside a HyperLink control instead.

Title:  
Name:  
Url:
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments   

Add To Your Reader

My Links

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<May 2008>
SMTWTFS
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Comment Stats

DayTotal% of Total
Sunday 1866.8%
Monday 37913.9%
Tuesday 45316.7%
Wednesday 50418.5%
Thursday 53519.7%
Friday 49418.2%
Saturday 1666.1%
Total 2717100.0%

Hour1Total% of Total
12:00 AM 652.4%
1:00 AM 682.5%
2:00 AM 622.3%
3:00 AM 742.7%
4:00 AM 572.1%
5:00 AM 1033.8%
6:00 AM 1084.0%
7:00 AM 1585.8%
8:00 AM 1716.3%
9:00 AM 1475.4%
10:00 AM 1716.3%
11:00 AM 1816.7%
12:00 PM 1886.9%
1:00 PM 1696.2%
2:00 PM 1605.9%
3:00 PM 1324.9%
4:00 PM 1073.9%
5:00 PM 923.4%
6:00 PM 913.3%
7:00 PM 963.5%
8:00 PM 833.1%
9:00 PM 782.9%
10:00 PM 792.9%
11:00 PM 772.8%
Total 2717100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 5.54144
Monday 5.22339
Tuesday 4.28419
Wednesday 7.67637
Thursday 6.90607
Friday 5.48411
Saturday 5.33160
Total 5.842717

Hour1 Entry MadeAvg.Total
12:00 AM 5.0035
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 7.0035
8:00 AM 5.35107
9:00 AM 6.32278
10:00 AM 6.47246
11:00 AM 4.41181
12:00 PM 6.88330
1:00 PM 3.00111
2:00 PM 5.41222
3:00 PM 8.64285
4:00 PM 4.0589
5:00 PM 5.92154
6:00 PM 4.52113
7:00 PM 9.67174
8:00 PM 9.80147
9:00 PM 5.05111
10:00 PM 5.4265
11:00 PM 4.5732
Total 5.842717

Learn More About Comment Stats
1 - All times GMT -8...


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles