Visual Studio and ASP.Net Path question
Question about paths while working in Visual Studio. In my master page I have some paths to load css files as well as javascript files.
My first question is if I use relative paths, should the relative path be from the location of the master page file? For example if I keep all my master page files in a folder off the site root called MasterPages should I assume that is the starting point for my relative paths to load the css files? If that master page is used to wrap an aspx file several directories down the tree is the hard coded relative path still valid?
Second question, is there a way to use absolute paths so that everything works on my local machine as well as when I move the fi开发者_如何学Cles up to the webroot? For example my app path on my local machine may be localhost/myappdir/default.aspx but when i move the app to the server there is no myappdir and the default.aspx is in the webroot. I do not want to have to change paths in the files after they are moved up to the server.
currently I have..
src="<%= VirtualPathUtility.ToAbsolute("~/lib/css/style.css")%>"
but this way Visual Studio cannot find the css file to update intellisence
If you use relative paths to your css/Javascript files, then they will need to be relative to the page, not the Master page.
This article does a very nice job of explaining the options you have in this situation, and towards the end they propose a nice solution to this type of problem, a user control that renders the script or link tag for you and calls ResolveClientUrl
to make the paths correct.
As a rule, you should be using server-relative paths (as in, /images/stuff.gif) to everything all the time. Using relative paths (as in ../images/stuff.gif) will screw you every single time, as will trying to rely on ASP.NET "Magic" such as VirtualPathUtility.ToAbsolute and ResolveClientUrl.
Occasionally, on the server you'll need to prepend that path with a tilda (as in ~/images/stuff.gif) so that it will correctly navigate the virtual directories that ASP.NET requires you to base all your projects in.
Naturally, this also means that you'll need to set your dev box up with multisite so that you can change your root to something like http://mysite.dev/ and ensure that all your server-relative paths work correctly. (Using the VS.NET built-in server would technically work around that too, but really, do you want to use that thing???)
Use the "~" operator to resolve everything relative to the root. Never use relative paths. Even when I'm not using themes, I use their syntax to get simple syntactic access to my CSS files by creating a folder structure like : App_Themes/Style/stylesheet.css Then in my ASPX page directives I add Theme="Style" and my CSS files will be automatically resolved - not exactly conventional but very effective :-)
UPDATE:
To resolve the JS, you could use the following in your master page code-behind:
string myScript = "js/footerFix.js";
Page.ClientScript.RegisterClientScriptInclude("myKey", myScript);
With IIS7 you do not need to change anything to get "multi-site" behaviour; this is baked in. For example you can have several sites as follows and reach them via URL without any separate configuration aside from creating the virtual directories:
localhost/project1
localhost/project2
localhost/project3
Put your script and stylesheet links in a <head Id="headRegion" runat="server" />
in the master page. Their src/href should be the absolute URL path that you get when running in WebDev.WebServer (eg /ProjectWeb).
In the Master Page OnPreRenderComplete(), rewrite any URLs inside headRegion.
Visual Studio can intellisense your scripts and css, and the project can be deployed under any virtual path.
protected override void OnPreRenderComplete( EventArgs e )
{
base.OnPreRenderComplete( e );
var root = Request.ApplicationPath;
if (root == "/") {
root = "";
}
foreach (Control c in headRegion.Controls) {
if (c is HtmlLink) {
HtmlLink hlink = c as HtmlLink;
hlink.Href = ReplacePath( hlink.Href, root );
} else if (c is LiteralControl) {
var literal = c as LiteralControl;
literal.Text = ReplacePath( literal.Text, root );
}
}
}
string ReplacePath( string content, string prefix )
{
return content.Replace("/ProjectWeb", prefix );
}
精彩评论