Visual Studio and ASP.Net Path question - asp.net

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 files 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 );
}

Related

CSS and image paths not working

Paths defined within master files are not working on a new server. They worked fine on production server and development machine. Here is an example of the file:
/HeadOffice/Styles/HeadOfficeCalendar.css
Unless I put full URL with the virtual name, the paths don't work.
working:
https://connect.server.co.uk/FesQA/HeadOffice/Styles/HeadOfficeCalendar.css
I can also include resolved URL within ASP>NET code tags but I don't want to change all those paths they are probably hundreds of them. so if the head office folder is in the same folder as master file it should just be able to reference like:
/HeadOffice/Styles/HeadOfficeCalendar.css
It seems the references within the master files and aspx files seems to work fine by adding ~ and runat = server. but images references within the CSS files are not working unless I include the full path.
DOESN'T WORK
url(/HeadOffice/Images/tlcorner.png)
DOES WORK
url(connect.server.co.uk/FesQA/HeadOffice/Images/tlcorner.png)
I know I've answered this before, but this has been known issue forever in VS.
Simple way to do this correctly is to drag the CSS file from Solution Explorer window to head section of master page in code view.
For other links on your site, make sure to include the runat="server" attribute and resolve your links like this (with "~" operator):
<img src="~/images/sample.jpg" runat="server" />

SilverStripe 3: Load/Create page outside of the CMS

is it possible to create a page outside of the cms?
For example:
I would like to use jquery .load() to load a segment into a current page.
Is it possible to create a html or .ss file somewhere in the theme folder eg: self-contained-page.html so if I then visit www.domain.com/self-contained-paged.html I will be able to visit this page.
While you can of course serve static files, you can also "ajaxify" parts of your page. Not sure if that's what you want to do, but in case someone else is trying to do something similar.
While you could use some fancy tools like pjax or history.js, you can also do it manually. I've recently done this with SS 2.4, but SS 3 should be pretty similar:
In your controller, add a public function so you can access it via /yourpage/load (or whatever you want to call it):
public function load(){
return $this->renderWith(array('AjaxLoad'));
}
In your templates/Layout add a file AjaxLoad.ss.
If you only want to serve that page via your jQuery .load(), simply add the content right inside the file.
If you want to use the piece of content both on your regular page and want to replace it with the ajaxified version, use <% include PageSnippet %> both on the general and the ajaxified page. Then simply define your content in templates/Include/PageSnippet.ss.
You can see it in action at http://www.contentaward.at/content-lab-vienna/608#details (click on the small images at the bottom of the page). Hope this makes it clear.
there is no problem with serving static html files from anywhere in your silverstripe installation, just note to always add the file extension to your urls, as otherwise silverstripe's url routing (using mod_rewrite, see the .htaccess file) will kick in.
also note to always use the full path to the file, so in case you placed your file in 'themes/mytheme/test.html' the url will be 'http://www.domain.com/themes/mytheme/test.html'
You can of course reference a html file in the theme folder just as you would do with a css file, f.e. :
www.domain.com/themes/yourtheme/self-contained-paged.html
If you dont mind to not have it in the theme folder you can also place it into root dir.
Or you can modify your .htaccess and apply some mod_rewrite or redirect rules to point into the theme folder.
If you want to use .ss files you probably have to use CMS pages.

How do I set a CSS url to an absolute location?

I'm working on an HTML5 mobile app and I initially have the background of a DIV item set through the CSS as follows:
background-image: url('images/ClanSpider.png');
In my app, I have a method that changes the background DIV based on a selection made in a dropdown list from a previous method using jQuery:
function ResetMyHonor()
{
ClanImage = 'images/Clan' + MyClanName + '.png';
$("#MyClanName").html(MyClanName);
$("#MyHonorBox").css('backgroundImage', 'url(' + ClanImage + ')');
}
All of this works fine when I'm on the root of my page. However, I have some links within the app using hash tags to navigate the page (such as #MyHonor). When I've navigated to one of these tags and call my reset function above, the image breaks. When I pull up the Chrome Inspector to look at the DIV tag, it says that the image it is trying to load is "images/MyHonor/ClanSpider.png" which doesn't exist.
I know the CSS url will generate links in reference to its location within the application, but it doesn't matter where I move the CSS files in the application.
Is there a way for me to rewrite what comes out of the url processing or an alternate way of specifying the background image of the DIV without doing any kind of server side processing? Ideally this app will run through the manifest cache feature of HTML5, so I won't have access to any server based languages.
Try putting a leading slash on those paths to represent the root.
ie use:
url('/images/ClanSpider.png')
instead of
url('images/ClanSpider.png')
From reading through your comments on the other answers I think you're creating a problem for yourself that doesn't really exist. If url('/images/ClanSpider.png') is going to work when you upload to the web server then the trick is to make it work the same way when working locally. By far the easiest way to do this, especially if your focus is an offline app which has little in the way of server side requirements (which I'm assuming is true, as you mentioned file:/// URIs), is to run a local web server.
Python ships with a module SimpleHTTPServer, if you have Python installed then starting it is as simple as going to your L5RHonor project directory in a command prompt and issuing the following command:
python -m SimpleHTTPServer
Then instead of accessing your files with URIs like this:
file:///H:/Projects/L5RHonor/images/ClanSpider.png
You will access them like this:
http://localhost:8000/images/ClanSpider.png
All your root relative file paths will now work correctly, as an added bonus the offline caching will work correctly in Chrome and you'll be able to see from the log in the command prompt window that it is requesting and caching the correct files according to your manifest.
The simplest solution is obviously adding a slash to the URL to make it absolute. That will work fine, but it makes it impossible to move the application into a sub-directory, or to move static resources to a different server. If that is a problem, there are various alternative ways.
If the number of possible background images is finite, you could define every one in a class of its own:
.bgSpider { background-image: url('images/ClanSpider.png'); }
.bgFalcon { background-image: url('images/ClanFalcon.png'); }
...
and then do an .addClass() to set the correct image.
Other than that, as far as I know, there is no way to specify a path relative to the style sheet (rather than the current document) when setting a background image path in Javascript. You would have to work with absolute paths, or define a root path in JavaScript, and use that:
// in the script head
imageRoot = "http://www.example.com/mysite/images";
// later....
$("#MyHonorBox").css('backgroundImage', 'url(' + imageRoot + ClanImage + ')');
The location of the CSS file is irrelevant, you are modifying the .style property of an HTML element. This is the same as using the style attribute.
As this is CSS embedded in the document, all URIs are relative to the document.
You probably want to start the URL with a /, or if you really want the absolute location specified in your question: http://
Try adding a / at the start of the URL?

How to Properly Reference a JavaScript File in an ASP.NET Project?

I have some pages that reference javascript files.
The application exists locally in a Virtual Directory, i.e. http://localhost/MyVirtualDirectory/MyPage.aspx
so locally I reference the files as follows:
<script src="/MyVirtualDirectory/Scripts/MyScript.js" type="text/javascript"></script>
The production setup is different though. The application exists as its own web site in production, so I don't need to include the reference to the virtual directory. The problem with this is that I need to modify every file that contains a javascript reference so it looks like the following:
<script src="../Scripts/MyScript.js" type="text/javascript"></script>
I've tried referencing the files this way in my local setup but it doesn't work.
Am I going about this completely wrong? Can somebody tell me what I need to do?
Thanks
Use ResolveUrl("~/")
<script src="<%=ResolveUrl("~/scripts/myscript.js") %>" type="text/javascript"></script>
~/ will get to you the root of your application, virtual or otherwise
Previous answers seem to assume that the Scripts directory always exists as a subdirectory of your application root. If that assumption is correct, and if the page is also at the root, then both of your earlier tags can be simply:
<script src="Scripts/MyScript.js" type="text/javascript"></script>
But my read of your second example is that Scripts isn't always a subdirectory of your application root (because the ../ at the beginning moves up a level, so Scripts would be a peer of your application root). That said, you did say the second example didn't work. :-) But if that's really the case, I'd strongly recommend adjusting one environment or the other so that the relative paths agree, and then always using relative paths as above.
The only reason for using ResolveUrl as far as I know would be if the pages in the application are in a folder structure and the tag may appear in a page at the root or in a page in a "subdirectory". If so, you can use ResolveUrl in both cases so you have an anchor point. I never author things that way, I always ensure I know where the page will be in the hierarchy (if there needs to be a hierarchy) and use an appropriate relative path for the current document.
You can use the HttpRuntime.AppDomainAppVirtualPath property to get the virtual path (if any) for your app and use that to fix up the javascript paths (using <%= ... %> in the <script> tags etc.)
You can further add a global javascript variable in your master page that exposes that value as well, so that any scripts that need to know the actual app root can access it that way.
Another way in MVC5:
1) in the layout html View file, place RenderSection in the place you need the script to be:
<html><body>
#RenderSection("scripts1", required: false)
</body></html>
note that you can change the "Scripts1" to be whatever name you like.
2) in your view html file, just call the "scripts1", doesn't matter where, with your path and js file name:
#Scripts1.Render("~/Scripts/MyScript.js")
3) make sure the MyScript js file is in the Scripts Folder of your project.
That's it.

ASP.NET Setting Flash file path for Object tag inside a usercontrol

I have a an ASP.NET user control where i wanto run a flash movie using flashplayer.How can i set the path of flash movie file properly so that this would work in all pages irrespective of the folders. ie; it should work inside a page in FolderA and a page in FolderASub1 which is in FolderA and a page in the Root folder too.My Flash file resides in a Folder called FlashGallery in root.My User control resides in a Subfolder in Root.
I am not sure how can use ~ here .Since its(Object tag to play flash) not a server control.
And infact i cant place the full relative path too.
Anythoughts ?
You can use a root-based path: /FlashGallery/movie.swf
Or you could generate a path string in your code, and place it in the aspx file like this:
Use an absolute path based off the root of your domain. Instead of using a relative url path like
"mymovieplayer.fla"
or
"../mymovieplayer.fla"
do this
"/flash/mymovieplayer.fla"
FYI: I use this (Free)Control: http://www.junasoftware.com/servercontrols/swfobject.net/download.aspx
You can use the '~' tilde to use relative paths to the site root and it will work on a master page, even if content pages are in different directories, you can use it like this:
<%# Register Assembly="SWFObject.Net" Namespace="Juna.Web.UI" TagPrefix="SWF" %>
.
.
.
Its FREEEEE!
Using a root based path is fine if you always know your site will be installed to the root, but this isn't realistic and best practise.
It would've been nice of we could use the server side relative path prefix of ~/ for the ... tag, but as you know it's not a user control so it just gets rendered out to the client as is. Below is a trick to allow you to specify the ~/ relative path for a client side script block.
I essentially use the VirtualPathUtility class and a protected method on the code behind of the page, master page, or control and it works very well for me.
Here's the method:
protected string GetPageRelativePath(string targetPath)
{
return VirtualPathUtility.MakeRelative( Request.AppRelativeCurrentExecutionFilePath, targetPath );
}
And here's how you can use the ~/ prefix in the script block:
<script type="text/javascript" src='<%=GetPageRelativePath("~/Scripts/MyScript.js") %>'></script>
Essentially you could use this with other src paths, even paths to images or Flash files.
Hope that helps.

Resources