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.

# re: URL Rewriting, the Image Web Control, and ~ 10/5/2008 10:59 AM Net Developer

Nice Job,thanks :)

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

My Links

Ads Via DevMavens

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<February 2010>
SMTWTFS
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213

Comment Stats

DayTotal% of Total
Sunday 2046.8%
Monday 42514.1%
Tuesday 51617.1%
Wednesday 55318.4%
Thursday 58019.2%
Friday 54718.2%
Saturday 1886.2%
Total 3013100.0%

Hour1Total% of Total
12:00 AM 772.6%
1:00 AM 812.7%
2:00 AM 682.3%
3:00 AM 822.7%
4:00 AM 692.3%
5:00 AM 1264.2%
6:00 AM 1183.9%
7:00 AM 1806.0%
8:00 AM 1926.4%
9:00 AM 1585.2%
10:00 AM 1876.2%
11:00 AM 1936.4%
12:00 PM 2016.7%
1:00 PM 1846.1%
2:00 PM 1695.6%
3:00 PM 1354.5%
4:00 PM 1153.8%
5:00 PM 1063.5%
6:00 PM 1013.4%
7:00 PM 1073.6%
8:00 PM 923.1%
9:00 PM 882.9%
10:00 PM 893.0%
11:00 PM 953.2%
Total 3013100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 4.94158
Monday 4.80384
Tuesday 4.08477
Wednesday 7.47680
Thursday 6.25675
Friday 5.02462
Saturday 4.78177
Total 5.413013

Hour1 Entry MadeAvg.Total
12:00 AM 5.2937
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 3.8550
8:00 AM 3.72134
9:00 AM 6.02295
10:00 AM 5.63276
11:00 AM 4.20193
12:00 PM 6.14350
1:00 PM 3.17133
2:00 PM 5.00230
3:00 PM 7.62320
4:00 PM 4.00108
5:00 PM 6.04169
6:00 PM 4.64116
7:00 PM 8.95188
8:00 PM 8.63164
9:00 PM 5.00115
10:00 PM 6.31101
11:00 PM 4.5732
Total 5.413013

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


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles