use of tilde (~) in asp.net path - c#

i'm working on an asp.net app, the following link works in IE but not in FF.
<a href="~/BusinessOrderInfo/page.aspx" >
Isn't the tilde something that can only be used in asp.net server controls. Where it will be replaced by an actual path?
Is it possible to use the tilde in an anchor tag? If so what does it mean?
When I'm at the root, the link works
www.myserver.com/default.aspx, click the link, ok!
www.myserver.com/otherpart/default.aspx, click the link, not ok!
The link generated by ASP.NET is:
www.myserver.com/otherpart/~BusinessOrderInfo/page.aspx
Is this by design?

You are correct, it only works in server controls. You've got these basic options:
Change to HyperLink to run as a Web Control:
<asp:HyperLink NavigateUrl="~/BusinessOrderInfo/page.aspx" Text="Whatever" runat="server" />
Or, run the anchor on the server side as an HTML Control:
<a href="~/BusinessOrderInfo/page.aspx" runat="server" >
Or, use Page.ResolveUrl:
...

HTML controls can be turned into server controls by adding the runat="server" attribute.
<a href="~/BusinessOrderInfo/page.aspx" runat="server">

The tilde refers to the application root directory, and will be translated correctly in control properties such as NavigateUrl.
My understanding is that if you use it in plain-HTML tags, it will not be translated by ASP.Net.

This function can also be used to resolve paths for non server elements
VirtualPathUtility.ToAbsolute($"~/App_Themes/Default/Icons/myimage.gif")

If you remove tilde and use forward slash only you will achieve the same result, i.e. pointing to the root folder on the current domain:
<a href="/BusinessOrderInfo/page.aspx" >

Using Web Paths and Tilde "~" in ASP.NET
~/ is not part of HTML, CSS, or JavaScript path systems.
~/ is an artificial path resolution character only ASP.NET or 3rd party products use.
~/ is a Web Server only path that gets translated to a new path by the code running on the server.
~/ is a character that tells ASP.NET on the IIs Windows
Server to find the "application root" of your website.
~/ resolves as a "Virtual Path" as it tells the server to find virtual or application root of a ASP.NET Web Application controlled by a given AppDomain on the server and resolve it from that new virtual root.
~/ in most cases resolves to the web root of any website right right after the domain, no matter what page or subfolder you are in when the path is called. In almost all cases this resolves to /. So the two are the same in MOST cases unless you set up a Virtual Application on the server.
~/ is really only useful when your website uses one or more Virtual Applications in a web server like IIs. These are artificial sub-applications under your web domain that add a new folder or path under a web root that do not truly exist but represent separate applications and processes managed by the server. This often creates one or more virtual application folders under your domain in IIs which ASP.NET and IIs manage when running separate instances of your ASP.NET website under one domain. See below...
Microsoft .NET is now using ~/ in Routing Attribute paths. When used they start the path back at the web root as an absolute path, but also override all controller or other attribute paths.
VIRTUAL WEB APPLICATIONS
In the old days, we used to create Virtual Applications in IIs Web Server to create two more web paths in order to isolate one or more web 'experiences' using the same domain. Each Virtual Path might be a "ghost" path that points back to the web root but creates an additional ghost folder under the web root. In many cases, that new virtual path pointed to a physical folder separate from the normal web path or even to computer hard drive path or mapping. ASP.NET with the right permission then ran web site code from there. The new virtual path shown to visitors of your web domain would then appear as part of the main site but run a second instance of your web application using a separate process run by ASP.NET (a separate AppPool or worker process).
~/ was then very useful in those cases. It was used in path resolution and easily mapped to the root of these new virtual application roots or paths created by the server, allowing you run multiple application under one website with no change to your paths in your ASP.NET code. The server-side code would then resolve the paths for you inside each virtual application with no changes to the code base.
~/ in those situations was extremely valuable as you no longer needed to manage multiple paths in your web app for each application if it ran in multiple virtual web applications under one website with different web roots. It could always find the new root in each application using ~/ rather than the true web root which was always http://example.com/
EXAMPLES
Most paths in ASP.NET using ~/ resolve to / in a normal website without virtual applications, and point all paths to the web root of the URL below. In most cases that is why ASP.NET ~/ is redundant. Just use /. Both point to the web root:
https://example.com/
However, if you added virtual directories to your domain, as this example below shows, ~/ inside each separate web application would resolve to two different web roots:
https://example.com/virtualapplication1/
https://example.com/virtualapplication2/
In the early days of ASP.NET, I always grabbed the application path using this code below stored in a global variable. This allowed me to fully control all paths from a relative application web root off the domain root or a virtual root no matter where my web application was moved to. But this path is what the ~/ replaced long ago. However, it still might be better as you can build paths from it dynamically on the server:
var myWebRoot = HttpContext.Current.Request.ApplicationPath;
My opinion is virtual applications like this are rarely used today as domains are cheap and subdomains are often used instead, like so:
https://app1.example.com/
https://app2.example.com/
All web paths should use absolute paths in every case possible /. The exception is CSS paths which are relative to the page source page or code calling them internally. Many say that means those absolute web paths break if you move them. But I argue, why would you need to reference the root for your website then suddenly change that? If you do, that should be managed on the server side and injected into your HTML and JavaScript, not the other way around.
Second of all, many Open Source, UNIX-based vendors are creating JavaScript API libraries that stumble around with dot paths which HTML and CSS do not support, like ./ or .
These are UNIX conventions that just mean to point to the local folder or the same folder the calling code is in. It's the same as NO PATH, so why use it? There are cases for their use, but the end result has zero affect on Web Paths. So I would avoid their use. The ONLY place they work in JavaScript reliably is in the new JavaScript Module in ECMAScript. But in proprietary API's like Google Angular, they are required.
For example these two image paths using UNIX local path conventions using ./ or . both fail in HTML and create missing image errors:
// These return broken image icons in browsers when using
// these unconventional UNIX local dot path conventions on the Web:
<img id="image1" src="./images/image1.png" />
<img id="image2" src="/images/.image2.png" />
So avoid all these deviant path system and stick with / absolute HTML paths and your code will always work for decades to come!

Related

moved web form does not load

I'm a newbie at asp.net and I have asp.net application with nested master pages. (.Net 3.5) I had a web form at root directory and I moved it a folder which I created under root. From this point I started to get "cannot use a leading .. to exit above the top directory" error while that web form loading. I digged on web and I tried prefixes "~", "/", "../" but I'm nowhere. my code as follows.
<li>
Add New Staff
</li>
I tried to create one more web form under "Staff" directory, but this form also generates same error while loading. Appreciate for help.
if i am not wrong you are using double code in href. it should be like this depending on your folder structure.
Add New Staff
And
For anyone who has found this thread, addressing relative paths has always created arguments over what is correct or not.
Depending on where you use the path to be addressed, it will depend on how you address the path.
Generally :
. and ./ do the same thing, however you wouldn't use . with a file name. Otherwise you will have the browser requesting .filename.ext as a file from the server. The proper method would be ./filename.ext.
../ addresses the path up one level from the current folder. If you were in the path /cheese/crackers/yummy.html, and your link code asked for ../butter/spread.html in the document yummy.html, then you would be addressing the path /cheese/butter/spread.html, as far as the server was concerned.
/ will always address the root of the site.
In ASP.NET Web Form, we normally use HyperLink server control to create URL as mason said.
<asp:HyperLink runat="server" NavigateUrl="~/Staff/New_Staff.aspx" Text="Add New Staff"/>
If you do not want use it, you can manually prepend with <%= ResolveUrl("~/") %>.
Add New Staff

What does Override application root URL really do?

The only place on the entire internet I could find an explanation is on MSDN:
Specifies an alternative path for the application root URL. Use this
option if the Web application root is not the root of your project.
From here I understood that "application root" is the path that retrieves when using tilde in ASP.NET. So I would expect that if I go to project's properties - Web - "Override application root" and specify another url then the tilde would map to that url.
But it doesn't. For example my web is on a virtual directory - http://localhost/WebApplication1
and on "Override application root" I try to specify http://localhost/WebApplication2 or http://localhost or http://WebApplication2 (which all exist on my local IIS). Now when I write
Response.Redirect("~/test2/login");
I expect it to redirect me to http://localhost/WebApplication2/test2/login.
But instead it redirects me to http://localhost/WebApplication1/test2/login as if I didn't override the "application root".
So what does this feature really suppose to do? Or maybe it's not working because I'm missing something and didn't define it properly?
Override application root URL doesn't change where the Application root is within your application. It changes the URL used to reach the application root. Because IIS does some hostname verification it's used to specify if you want to reach your application by a means other than localhost:[PORT].
For instance, if you override it to www.myapp.com you can then reach your application by adding this to your hosts file:
127.0.0.1 www.myapp.com
This might be especially useful if you're making your application available to a remote device (a virtual machine on your computer, or a mobile device on your network) because they would be unable to navigate to localhost as the application address.

Get full url of a page, for a website in a subfolder of another website

I'm using Sitefinity (6.1), ASP.Net and the 4.0 framework.
We have a sitefinty website already hosted on IIS as a website.
For licencing reasons we want to add a new site, also made with Sitefinity to the same
website as a subfolder.
Lets say website 1 is Foo and the new website is called Bar.
The problem is when I get or use the relative path form Bar, I really get the path from Foo.
So atm I am using a hack to get urls to work. I use the relative path and then insert Bar man ually.
e.g. page is called home. ~/home resolves to http://www.Foo.com/home. when it should be http://www.Foo.com/Bar/home, so I just add the Bar in manually atm.
There must be some way in ASP.Net or Sitefinity or MVC to say this is my page, give me the full url.
Has anyone has experence resolving urls for websites in another website?
Technically you're looking for an answer like this:
How do I get the full url of the page I am on in C#
But with regards to Sitefinity you're bound to run into trouble cause it has many 'under water' references to the site root. Take a look for instance in the backend under Administration >> Settings >> Advanced >> Virtual Paths.
So you're bound to run into some cross contamination and end up with two broken sites.
While I'm not for dodging licenses, here's a few suggestions:
They do allow unlimited subdomains.
Install 'bar' as an IIS application that way ~/ will resolve properly.
Change Administration >> Settings >> Advanced >> System >> SiteURL settings.
That last option will allow you to set the site-root (not iis/asp.net level but sitefinity level) at which point you could retrieve a proper url through Sitefinity API with page.GetFullUrl();
If anyone is wondering I found a simple solution that works in all environments.
string url = node.Url.Replace("~/", "./");
Where node is of type SiteMapNode (but you can get the url however you want of course).
That gives the correct path if there is a subfolder or not.
This string url = node.Url.Replace("~/", "./"); won't work if the page is not at the root level.
For example for this url: "xxxx://www.foo.com/sitename/sitefolder/sitepage" it will return "xxxx://www.foo.com/sitename/sitefolder/home", instead of "xxxx://www.foo.com/sitename/home"

Reference file outside of Web site directory

How do I reference a file outside my web site's root directory?
For example my website is located at C:\dev\TestSite
I am using ASP.NET with XSP. The webapp will be deployed on Apache using mod_mono.
I have images in C:\images and I would like to do this:
<img src="C:\images\logo.gif"/>
Your img tag's src value is going to be sent to the client. You need to specify those paths relative to your document root. Your best bet is to set up a virtual folder (in IIS, alias is the apache equivalent) to point to the c:\images path and then change the mentioned tag src path as follows
<img src="/images/logo.gif" />
To do this in apache, you need an alias in your httpd.conf. The line looks like this
Alias /images c:/images
Here's the docs http://httpd.apache.org/docs/2.0/mod/mod_alias.html#alias
While it might be possible to do this through some hacky method, it's not a good idea. Allowing the IIS account to access files/folders on the greater file system would be a big potential security hole.
The best way to accomplish this is to use IIS Virtual Directories. Put your content in folders dedicated to supporting the site, DO NOT make your entire C: drive a virtual directory.
I'm going to assume that C:\images\logo.gif is the path on the server, and not the path on the client.
The src attribute is interpreted by the html client (i.e. Internet Explorer). The client can't see anything outside of your web directory. In fact, the client can only see things inside your web directory if you've provided permission for them to do so. Thus, this isn't an ASP.NET issue, but an issue of how web clients have access to web servers... which is designed this way for security.
In order for your application to use these images, you've got a couple of options that immediately spring to mind - neither of which is ideal:
The ASP.NET code (in the codebehind) is going to need to go and grab the file, and serve it out in the html stream that is being served to the client, which is more a complex task than I suspect you are willing to embark on.
The ASP.NET code (using System.IO) is going to need to go and grab the file from it's home location in C:\images\logo.gif and copy it to a location that is accessible to the client - you could create a temporary directory, copy your image to it, serve it out, delete it, delete the directory.
Both of these are certainly hacks that should be avoided if possible, but if you're adamant that this is what you want to do, this will allow you to do it via your ASP.NET app.
The most ideal solution is to add C:\Images as a virtual directory to your document root, i.e. /ImageCentral - this way you can have images that are central to multiple websites stored in this directory, it can then be referenced by clients for any of the websites just by adding virtual directories to each of them pointing at the central images folder. As DaveSwersky points out, don't make any directories containing sensitive information virtual directories, the minute you add a virtual directory to an externally visible website, you're giving people free reign to any of the information in it.
Good luck
You can't do this from within the HTML code of your page. The HTML page can only reference web accessible content (in regards to images, CSS, javascript, etc). You could create a virtual directory that points to your images folder so that it becomes web accessible.
EDIT:
The apache way inside of your conf file.
Alias /images "C:/Images"
And a little walkthrough from some dude.

Wildcard mapping for ASP.NET and issues with PHP

I have an application written in .NET 3.5 with C# as the language. I'm using Web Forms, but using url routing with the routes defined in my global file. Everything is working as expected. In order for the pretty paths (see: user/665 instead of user.aspx?uid=665) to work properly, I had to add a wildcard mapping in IIS5.1 (local box, not test, staging, or production) the aspnet_isapi file for the 2.0 framework. Everything works fine.
Now, my site needs a plugin for PHP. However, the PHP files are now being serviced by ASP.NET due to the wild card mapping, and hence are not processed by the PHP interpretter. Is there any way to get around this? Would I have to add some sort of handler to my web app that will take all PHP requests being handled by the ASP.NET framework and have them routed to the PHP engine? Is there an easier way? Maybe a way to exclude them in the web.config (PHP files) and have them served by the proper PHP engine?
Thanks all!
-Steve
This is a solution, but is not an elegant way (IMHO):
Create a virtual directory
Have it point to the folder with the files (in this case, a PHP plugin)
Give it the proper permissions
Change the config options for the virtual directory in IIS and make sure the wildcard mapping for that directory is removed.
This works like a charm for my situation. However, is there any way to not have to deal with virtual directories?
The problem is that the PHP extension needs to be registered.
In IIS Manager right-click on Default Website -> Properties -> Home Directory -> Configuration
Under Application Mappings make sure that .php is added and is it pointing to PHP.EXE. There should be an entry like this: extension .php, executable path C:\PHP\PHP.EXE %s %s
From what I gather, the problem is that ASP.NET is attempting to route your PHP requests, so what I would do is add a StopRoutingHandler() to your routes in the global.asax. Something like this should work:
routes.Add(new Route("{resource}.php/{*pathInfo}", new StopRoutingHandler()));
Edit: Be mindful that routes are processed in order, so I would add this to the top of your routes.

Categories

Resources