ASP.NET WebForms: Why do relative paths within use

2019-07-21 15:14发布

问题:

Rewriting Question

I cannot, for the life of me, get relative image paths work consistently inside usercontrols between using VS's dev server and publishing to a remote IIS server. I do not want to make my image a server tag by adding runat="server". I want it to be strictly client and I do not want to use any hocus pocus code hacks. I want to resolve the disconnect, so here is my problem:

My images are stored in ~/images. My usercontrols are stored in ~/usercontrols/anothersubfolder.

When I do this...

<img id="myimage" src="../../Images/help.png" alt="" />

...the image loads when using the VS dev server (localhost), but not when I deploy to a remote IIS virtual directory. However, when I do this...

<img id="myimage" src="<%=Request.ApplicationPath %>/Images/help.png" alt="" />

...it works when I publish remotely, but not using the dev server!

I need a solution that works for both the VS dev server AND when I publish remotely. As I said, I do not want to add runat="server" to my image tag or use any code hacks. There is a disconnect here and I want to know how to go about resolving that.

回答1:

Try it like this:

<img src="~/Images/indicator.gif" border="0" alt="" runat="server" />

Avoiding problems with relative and absolute URLs in ASP.NET

Control.ResolveUrl versus Control.ResolveClientUrl versus VirtualPathUtility.ToAbsolute

ResolveUrl vs. ResolveClientUrl



回答2:

It seems like you've found your own answer: The location of the ascx control doesn't change relative paths. The aspx page loading the ascx control ultimately determines the paths (this will extend to your CSS and JS files, if you're using any).

I "solved" this problem by never using relative paths. My src attributes always look like <img src="/<appfolder>/Images/<filename>.<extension> />.

It's worth noting that I change my website properties and select Use Local IIS Web Server under the Web tab of the properties page. Since I don't use the Visual Studio Development Server, your mileage may vary depending on your project's configuration.



回答3:

As others already answered, a user control ".ascx" is being loaded by the page that contain it and btw it is the same thing with master pages - they are being loaded by the page. So any relative path you describe in your script is relative to the location of the page.

So putting <img id="myimage" src="~/Images/help.png" alt="" runat="server" /> or simply use the server side control for image, will solve your problem technically..

But from what I understand your problem is less technical as you probably knew that..
So left to assume is that your problem is more conceptual regarding the morphing of a simple html control into what you describe as 'code-hack'.

You must acquire yourself with the "standards" regarding working with asp.net,
and to do that you first need to understand that asp.net is a system that aims to generate a page on server side and afterwards deliver this newly created dynamically generated page to the client side - this is the main benefit of working with asp.net and is the highest principal of it!!
This is why your page in asp.net is not .html - it is .aspx even though the script generated later will only be html.

So if you agree with my previous paragraph you also understand that any .aspx page you create is being processed by your server before delivery and the script tags you put in it are just a set of instruction regarding of how to process it dynamically. adding runat="server" only means that the attributes and content of a script tag requires server side special attention during the generation process of the resulting html page.

The aspx page you have in VS and the aspx page generated for your browser are not the same entity.
runat="server" never appears to the script being delivered to your client side.

Writing script in asp.net is not writing html - it is writing meta instructions that aim to influence what the generated html would contain.

I hope that by now I convinced you to use the provided best technical solution as a normal and natural standard in asp.net with no grief or regrets.



回答4:

when you run it locally you are using your folder you created and you are working in, after publish your control maybe ended up in a controls folder created by VS and your original filestructure with 2 folders is gone. Check the filesystem after publish and reorder your work-folders.



回答5:

Relative paths in user controls are relative to the page they appear on, not the location of the user control. This is basically what you are stating in your update, I believe.

You should post your update as answer and accept it, or accept my answer, whichever is your preference :)



回答6:

Just as another possibility, ASP Parent paths are disabled on IIS by default, could this be the cause of your issue?

This article talks about how to resolve the issue if it is this. Basically, you can resolve it in a couple of ways, but the easiest is to go into the ASP settings on the IIS site and re-enable parent paths.



回答7:

<img id="myimage" src='<%= ResolveUrl("~/src/....") %>'/>