How to remove virtual path from root url of dev web server?

S

Steve Franks

I am using VS.NET 2005 beta 2. When I run my project locally using the
default ASP.NET Development Web Server it runs using a root address like
this:
http://localhost:11243/testsite/

However when I deploy to a remote test server running real IIS, the real
root of my application becomes:
http://localhost/

What I want to do is have it so that on my local machine the asp.net dev
server does not use the virtual root, and instead uses:
http://localhost:11243/

The reason for this is so that my URLs will work.

For example I have to specify a background image url in my style sheets, and
a path like /images/whatever.gif is translating differently depending on
whether I run this locally in dev or remotely in production.

Thanks,

Steve
 
S

Steve Franks

I can see how writting a basic httpmodule to remove part of the path would
be a prety easy solution.

However the downside is that this module would then have to run in
production and add a lot of overhead. Every request would have to be
checked to see if it matches say "/devsiteroot/images/" so it could rewrite
the request as just "/images/". And I can't have the filter running on say
just the dev machine and disable it on production because I use Copy Web and
other such files to keep the production and dev sites in sync.

How are you guys handling this. It is quite messy IMO. I also have a
related issue in that some html attributes such as BACKGROUND cannot be done
server side so you cannot even use "~/whatever". For example you cannot do
a HTML table BACKGROUND with runat=server...

Steve
 
J

Juan T. Llibre

Use ~/images/whatever.gif

The tilde ( ~ ) signifies the application's root in ASP.NET.

All URLs will be relative to the root directory,
no matter where they are physically located.



Juan T. Llibre
ASP.NET MVP
ASP.NET FAQ : http://asp.net.do/faq/
==========================
 
S

Steve Franks

Right. However there is a big catch here. What do you do for HTML that
needs to be written out that is not part of a server control?

For example the BACKGROUND attribute of a HTML TABLE statement. You cannot
do:

<table border=0 width=100 background="~/images/something.gif" runat=server>

That will just result in the HTML being sent to the browser literrally as
background="/~images/something.gif" which of course does not resolve so the
background image does not load.

Same problem exists with stylesheets. For example if you need to specify a
URL in a style sheet.

What is the best way to handle that situation? Seems pretty messy.

Thanks,

Steve
 
S

Steve Franks

Its my understanding that the "~" special character is only interpreted by
server side controls. So I thought I'd try something like:
<table border=0 width=100 background="~/images/something.gif" runat=server>

To see if somehow magically ASP.NET would update the background url to
expand the ~ character, but this was wishful thinking I guess :)

Can you see the challenge I am facing here?

There are some parts of HTML such as the BACKGROUND attribute of a table
cell, and URLs used in style sheets, which cannot be done using server side
controls where the option for automatic conversion from "~" to the real path
would be performed. This leaves me scratching my head as to how to address
it.

As a specific example, assume you have a /images directory that contains a
graphic you want to use for a table background.

If you do this:
<table border=0 width=100 background="/images/something.gif">

then this is wrong when developing locally because of VS.NET and the
application name. So on my local dev machine the real path to the image is
really "/mysite/images/something.gif" yet on production its just
"/images/something.gif".

So I cannot hard code the URL either way, because it will work on dev but
not production, or vice-versa.

And, I cannot do this with the ~ character:

<table border=0 width=100 background="~/images/something.gif" runat=server>

because the table tag does not run at server - and even if it did I don't
think ASP.NET is coded to convert the ~ in that situation.

Now I suppose I could do something like use MapPath to dynamically figure
out what my document root structure was like at run time, and then do this:
<table border=0 width=100 background=" <% Response.Write(myRoot)
%>/images/something.gif"> but that would be VERY ugly and messy to do.

Certainly others have faced this so I am wondering if either I am just doing
something completely dumb and overlooking the obvious, or if not what is
being done about it the right way.

Worse case scenario - perhaps VS.NET 2005 b2 could just give me the option
to run without appending an application name when running locally in the
designer (just give me http://localhost:port/page.aspx and not
http://localhost:port/appName/page.aspx) .

Thanks,

Steve
 
J

Juan T. Llibre

You are getting yourself really complicated over something quite simple.

The only time you use server-side tables is when
you want to create the cells, etc., in code.

See :
http://beta.asp.net/QUICKSTART/util...net/samples/ctrlref/standard/Table/Table1.src
for an example of that.

re:
If you do this:
<table border=0 width=100 background="/images/something.gif">
then this is wrong when developing locally because of VS.NET and the application name.
So on my local dev machine the real path to the image is really
"/mysite/images/something.gif" yet on production its just "/images/something.gif".

Use : <table border=0 width=100 background="images/something.gif">

*Notice there's no leading slash...*

That is a relative URL to the images subdirectory of your application,
no matter where the application itself is located.







Juan T. Llibre
ASP.NET MVP
ASP.NET FAQ : http://asp.net.do/faq/
==========================
 
S

Steve Franks

Use : said:
*Notice there's no leading slash...*

That is a relative URL to the images subdirectory of your application,
no matter where the application itself is located.

Yes, but doesn't that force me to always have an images folder within each
section of my site?

For example my directory structure needs to be set up like this:
/
/companyinfo
/productinfo
/productinfo/productA
/productinfo/productB
/freestuff

So now let's say I have to reference the table background image from page
/productinfo/productA/details.aspx. If I'm using:
<table border=0 width=100 background="images/something.gif">

Then don't I have to have a /productinfo/productA/images folder that
contains something.gif.

Then let's say I have to reference this background image from page
/companyinfo/about.aspx. If I'm using:
<table border=0 width=100 background="images/something.gif">

Again won't I have to have a /companyinfo/images folder that contains
something.gif.

So every folder where a aspx resided would need to have its own images
folder, and that folder would wind up replicating all the other image
folders. That would be messy and a maintenance issue.

Do you see the challenge here, or perhaps I am just completely missing the
boat? It seems though that with the relative "images/something.gif" format a
images folder will be required in every folder that contains a page that
references the images. I certainly do not want that- I'm looking for a
solution so that I can have one common images folder that is shared and
accessible as needed from every page in the site regardless of what
directory it resides in.

Please let me know what you think. Thanks Juan you have been a big help!

Steve
 
J

Juan T. Llibre

re:
Yes, but doesn't that force me to always have an images folder within each section of my
site?

No. You only need one "images" folder for each *application*.
You should have separate image folders for different apps.

You can use a fully qualified path, too.

<table border=0 width=100 background="http://yourserver.com/yourapp/images/something.gif">

This is an HTML issue and not an ASP.NET issue.



Juan T. Llibre
ASP.NET MVP
ASP.NET FAQ : http://asp.net.do/faq/
==========================
 
S

Steve Franks

Juan,

I apologize. Either I am being very stupid about this or am doing a poor
job explaining the problem...

I tried what you just posted an the images are not found if I use the
"images/whatever.gif" format. As I mentioned in that post, that approach
would require even folder where a page ran from to have a images subfolder
with the images in there. "images/whatever.gif" means relative to the dir
I'm in now, go one step deeper into the images directory. So I'm not sure
how you are saying that "images/whatever.gif" will always take you to the
root (/images) images folder. Basic html says that does not work.

Try this basic exercise and I think you'll see exactly the challenge I am
experiencing:

1) take any project within VS.NET 2005 beta 1 running with the local dev web
server it uses by default (not IIS)

2) create a folder off the root called "steveimages" and place any graphic
in there

3) create a folder off the root called myproducts. Inside of this folder
create a basic .aspx web form that just has a basic HTML table with a
background image and point it to your image in the steveimages folder, like
this:
<table border=0 width=100 background="images/something.gif">
<tr><td>this is a test</td></tr>
</table>

4) Run the page. The image will not be in the table. Look at the logs and
you'll see a 404 with it trying to find images/something.gif.

That works ust fine but only in development. As soon as you publish this to
a real IIS server where "yourapp" is not part of the root, it breaks. Code
it instead as <table border=0 width=100
background="http://yourserver.com/yourapp/images/something.gif"> and then it
works ok in dev but breaks in production. This is the point of what I've
been trying to say all along.

I do agree its a HTML issue, but one caused by the VS.NET dev web server
that insists on appending an application name in the URL.

To further illustrate that this is indeed a significant issue, see this
article http://www.codeproject.com/aspnet/Multisite.asp . This also
highlights similar issues. However using the type of approach the author is
referring to would require me to write a HttpModule that rewrites the
request dynamically. That would work just fine, but it would require me to
run this in production and I do not want to put all requests through an
HttpModule in production.

Can you see what I am driving at here? I cannot understand how many others
are not tripping over this same thing.

Thanks,

Steve
 
S

Steve Franks

Scott - great idea - and it works!

I haven't looked into the Themes part of it, and it may be more than what I
need, but I'll check it out.

In summary here's how I did this:

1) I use a server-side link control runat=server and set the location to be
"~/mystyles/styles.css". Since this is a server side control it translates
the root path for me nicely.

2) I removed the BACKGROUND tag and instead created a class as you suggested
with a background-image and assigned this class to the TABLE tag:
<table class="tablebg" width=100 border=0>

3) I created the style inside styles.cdd with URL(../images/something.gif).
The "mystyles" and "images" folders are both off the root, so the ../ allows
me to reference it. The tip that the browser is smart enough to pull the
image relative to the style sheet was very helpful here too.

Now it runs great from both production and dev. Although this thread is
quite long, I hope others will find this useful. I imagine many first time
asp.net 2.0 developers are going to trip all over this like I did.

The only downside to using the style to create the table background image is
that the background image loads pretty late relative to the rest of the page
loading. So for the 5 seconds or so that it takes the page to load, the
table looks a bit odd/misformatted until the browser paints the background
image in. This did not happen when using the BACKGROUND attribute directly
in the HTML.

Any idea how to work around that and/or to force the browser to load that bg
image more quickly in this circumstance?

Thanks again to all,

Steve
 
J

Juan T. Llibre

re:
As soon as you publish this to a real IIS server where "yourapp" is not part of the
root, it breaks.

Why do you develop in the root of your development server ?
You shouldn't be developing in the root directory.

That's why you are having to go through all the contortions
you're going through.

If you develop in your root directory, that wipes out
the possibility of having additional applications in your server.

Treat your development server as a "real server". It is one.

Even if Scott's workaround works to solve your problem, and it does,
it winds up becoming extra -useless- code, because you're going against
a basic ASP.NET development tenet : don't create an application in the
IIS root directory.

If you do that, you'll wind up nesting applications.
That's not a good idea.



Juan T. Llibre
ASP.NET MVP
ASP.NET FAQ : http://asp.net.do/faq/
==========================
 
S

Steve Franks

Why do you develop in the root of your development server ?
You shouldn't be developing in the root directory.

I'm not intentionally doing this and do not understand the correct ASP.NET
development tenet so hopefully you can help me understand this better.
That's why you are having to go through all the contortions
you're going through.

Makes sense that something is fundamentally wrong, because its very messy.
If you develop in your root directory, that wipes out
the possibility of having additional applications in your server.

As mentioned above I'm not intentionally developing in my root. Here's what
I did. I ran VS.NET 2005 beta 2 and created a New Web Project with a name
of "mysite". When I press F5 to run the application, the VS.NET development
web server (not IIS) runs the project which I like very much, using a url
like http://localhost:someport/mysite/default.aspx.

Notice how it adds the name of my application "mysite" into the URL. If it
is removed to be just http://localhost:someport/default.aspx then the site
does not work, understandably. Additionally the full url to things like the
images directory is like "/mysite/images".

OK, so now I go to deploy to the production web server that is a real IIS
server that my ISP set up for me. However on THAT server there is no
"mysite" part in the path. I run the site just by going to
www.whatever.com/default.aspx and the page loads. Now in this case the full
url to the images directory is just "/images" and any reference in my html
to "/mysite/images" results in a 404.

So in this situation "/mysite/images/" is needed for code running on dev,
and "/images/" is needed for code running in production. Try to use the
same exact code on each and it works on one but not the other.
Treat your development server as a "real server". It is one.

I am very interested in what you mean by that, but don't understand what you
are saying.

I would love to have my dev server to run my site at
http://localhost:someport/default.aspx and not add the "mysite" part, but it
does not seem like the local test dev web server works that way (only IIS).
Even if Scott's workaround works to solve your problem, and it does,
it winds up becoming extra -useless- code, because you're going against
a basic ASP.NET development tenet : don't create an application in the
IIS root directory.

What do you mean by "don' create an app in the IIS root directory"? Is this
something that I'm doing wrong with the setup in developer or on my
production server? If its on the production server side I'm not sure if
there's anything I can do about it, as it is a shared server.
If you do that, you'll wind up nesting applications.
That's not a good idea.

I agree it sounds like I'm using the wrong approach. However I'm not sure
specifically what I should be doing different. Can you please provide an
overview of how this should be best set up, both in terms of my development
and production environment. Please keep in mind that I do not build lots of
web sites - just this one.

Thanks!

Steve
 
J

Juan T. Llibre

re:
When I press F5 to run the application, the VS.NET development web server (not IIS) runs
the project which I like very much, using a url like
http://localhost:someport/mysite/default.aspx.

Notice how it adds the name of my application "mysite" into the URL. If it is removed
to be just http://localhost:someport/default.aspx then the site does not work,
understandably. Additionally the full url to things like the images directory is like
"/mysite/images".

Steve,

You are going to laugh when you see how easy it is to eliminate that problem.

To specify the Web server for a Web site, open your local website and,
in the Solution Explorer, right-click the name of the Web site for which you
want to specify a Web server, and then click Property Pages.

In the Property Pages dialog box, click the Start Options tab.
Under Server, click Use custom server.

In the Base URL box, type the URL that Visual Web Developer
should start when running the current Web site. You can use localhost.

From that point on, the VS.NET IDE will not use the internal web server,
but will use IIS to open your pages, i.e., if you are working on default.aspx,
it will be opened as : http://localhost/default.aspx

That should get rid of *all* your URL referencing
problems without requiring workarounds.

If it doesn't, please post back.

I *never* use the internal server, except for file-based projects.




Juan T. Llibre
ASP.NET MVP
ASP.NET FAQ : http://asp.net.do/faq/
==========================
 
S

Steve Franks

You are going to laugh when you see how easy it is to eliminate that
problem.

To specify the Web server for a Web site, open your local website and,
in the Solution Explorer, right-click the name of the Web site for which
you
want to specify a Web server, and then click Property Pages.

In the Property Pages dialog box, click the Start Options tab.
Under Server, click Use custom server.

In the Base URL box, type the URL that Visual Web Developer
should start when running the current Web site. You can use localhost.

From that point on, the VS.NET IDE will not use the internal web server,
but will use IIS to open your pages, i.e., if you are working on
default.aspx,
it will be opened as : http://localhost/default.aspx

That should get rid of *all* your URL referencing
problems without requiring workarounds.

That sounds great! Yes that would indeed eliminate this problem entirely.

I tried this but I'm having some difficulty with it. I followed your steps
carefully, and when I go to run the site with CTRL-F5 it does indeed launch
the browser at http://localhost/default.aspx. However I get a 404 error.
This is understandable I guess because I did not create any mapping so that
IIS knows that http://localhost files are in the directory where my Visual
Studio files are. Since you did not mention that as a step, I did not think
it was necessary. Is it? If so, do I just create a new web site using IIS
MMC and give it the base root to where my VS asp.net applications are
stored?

Also as a side note I tried running with F5 but got an error dialog box that
said it could not continue because debugging was not enabled. I didn't mess
with this yet as I assume its just a basic setting under IIS somewhere.

Steve
 
J

Juan T. Llibre

re:
If so, do I just create a new web site using IIS MMC and give it the base root to where
my VS asp.net applications are stored?

You could do that.
Creating a new web site would land you in a virtual directory :

http://localhost/yourwebsite/default.aspx

You could also change the base directory for your default web site.
That would enable you to develop in the root directory.

http://localhost/default.aspx

That's what you originally wanted, right ?

Change the default directory for IIS by selecting the "Home Directory"
tab after selecting the "Default Web Site" property pages ( right-click
on "Default Web Site" in the MMC ).

Make sure you do *not* add a trailing slash to the directory path!

i.e., use : c:\VisualStudio\restofpath
and not c:\VisualStudio\restofpath\

re:
Also as a side note I tried running with F5 but got an error dialog box that said it
could not continue because debugging was not enabled.

That should go away as soon as you create your Application.

Enable debugging by setting <compilation debug="true"/>
in the Web.config file located in the application's root directory.




Juan T. Llibre
ASP.NET MVP
ASP.NET FAQ : http://asp.net.do/faq/
==========================
 
S

Steve Franks

I've got it working. Thanks for all the great help.

Its disappointing that you cannot create more than 1 main root web under XP.
I found some utilities that work around that to use one at a time rather
than manually switching it via MMC.

Also for anyone else following along - I also had to change my default web
to use ASP.NET 2.0.x.x using the ASP.NET tab in the properties due to a
xmlns error report.

I kind of like the dev web server that comes with VS. Too bad there is no
way to have it run a site as the root instead of forcing you to have an
application name in the root - that was the root cause of all this.

I greatly appreciate all your help Juan and hopefully this thread will help
others.

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top