Reputation: 6763
As you know, ASP.NET MVC stores view markup in a Views directory, which is hierarchically incompatible with the URL routes that are used in an ASP.NET MVC web application. On the opposite end, in ASP.NET Web Forms (and in ASP.NET MVC, too), URLs can and usually do have nested "directories", or rather path separators, and this combined with the fact that web applications are often not hosted in the root path of a URL but rather in a sub-directory i.e. "/stuff/here/MyActualApp", it is necessary to use a script path relative to the root of the application rather than relative to the root of a URL. Meanwhile, however, Visual Studio script intellisense dictates that URLs map relatively to the file being edited.
Further, I've run into a lot of problems with using runat="server" to virtualize the root path to support "~/", such as the head tag needing to also be runat="server", and this introduces all kinds of other constraints.
Finally, one more thing: if the minified flavor of a script like jQuery is referenced in addition to the intellisense-ready flavor, Visual Studio will balk on it. So you almost have to use escaped code to keep VS from balking.
So I've been using this syntax, or variations of it, in Visual Studio 2010 since VS 2005 for including script in my ASP.NET view markup to deal with the discrepancies nested folders for ASP.NET MVC view files (which do not line up with actual URLs) as well as the need to use the vsdoc flavor of jQuery instead of the minified version so that I get intellisense working.
<%if (false) { %>
<script src="../../Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>
<% } %>
<%= "<script type=\"text/javascript\"" src=\""
+ ResolveUrl("~/Scripts/jquery-1.4.1.min.js") + "\"></script>"%>
Aside from using a CDN URL, is there a better way than this? It's ugly. I wish Microsoft could have addressed this by now without resorting to ScriptManager tags (which require server-side forms as well as make the markup even more verbose).
Note: My issue is not with the Intellisense support so much as the last line in the code above, having to emit a line rather than just using real markup. However, I also want intellisense support readiness, too.
Upvotes: 2
Views: 2607
Reputation: 6763
In ASP.NET MVC 4, Razor has become smart enough to support "~/" detection. Hopefully the VS11 IntelliSense tooling will keep up with this.
<script src="~/Scripts/Controls.js"></script>
New in ASP.NET MVC4: Razor changes (Alexander Beletsky)
Meanwhile, the Visual Studio tooling and the jQuery source (since jQuery was used for reference in the question) have both been heavily modified since the question was originally asked. RickAndMSFT's answer did not apply at that time. At the current time, his answer is correct; however, since this is a moving target it appears that by the end of this year one would just reference the script directly and Razor and revised VS tooling will take care of everything.
Upvotes: -1
Reputation: 22800
As you know, ASP.NET MVC stores view markup in a Views directory, which is hierarchically incompatible with the URL routes that are used in an ASP.NET MVC web application
That is incorrect. In what way do you think the default view directory is incompatible with routing?
On the opposite end, in ASP.NET Web Forms (and in ASP.NET MVC, too), URLs can and usually do have nested "directories", or rather path separators, and this combined with the fact that web applications are often not hosted in the root path of a URL but rather in a sub-directory i.e. "/stuff/here/MyActualApp", it is necessary to use a script path relative to the root of the application rather than relative to the root of a URL
it is necessary to use a script path relative to the root of the application rather than relative to the root of a URL
WHat does root or the Url mean? MVC doesn't use nested directorys by default (unless you set RouteExistingFiles to true) What does it mean for a URL to have nested directories? MVC routing uses segments not path seperators.
applications are often not hosted in the root path of a URL but rather in a sub-directory More correctly, apps are hosted in a vdir which is not at the root level. With MVC 3 and lower you need to reference static resources (css, javaScript) using the @Url.Content helper.
With MVC 4/Beta + Razor and higher, you no longer need to use the @Url.Content helper.
Further, I've run into a lot of problems with using runat="server" to virtualize the root path to support "~/", such as the head tag needing to also be runat="server", and this introduces all kinds of other constraints
You should never use runat="server" with a MVC application to virtualize the root path.
the need to use the vsdoc flavor of jQuery instead of the minified version so that I get intellisense working. That again is incorrect. You should NEVER reference the vdoc versions directly. Visual Studio/VWD detects when a .vdoc version of a script file is present and enable intellesence.
Your helper approach is probably the best route. You could modify my helper approach http://blogs.msdn.com/b/rickandy/archive/2011/05/21/using-cdns-to-improve-web-site-performance.aspx
Typically folks comment out the .min references for development the switch comments for production to use the minified version. We are actually working on an approach to toggle development/production using minificatin/bundling. see RequestReduce. and http://weblogs.asp.net/scottgu/archive/2011/11/27/new-bundling-and-minification-support-asp-net-4-5-series.aspx
Upvotes: 2
Reputation: 26638
We use SquishIt. It combines and minifies the files, too, and supports css (and even dotLess).
<head>
<%= Bundle.Css()
.Add("~/media/css/style.less")
.Add("~/media/css/print.css")
.Add("~/media/css/media.css")
.Render("~/media/css/styles_#.css") %>
<%= Bundle.JavaScript()
.Add("~/media/js/jquery-1.4.3.js")
.Add("~/media/js/jquery.equalHeights.js")
.Add("~/media/js/jquery.cycle.lite.1.0.js")
.Add("~/media/js/swfobject-2.2.js")
.Add("~/media/js/site.js")
.Render("~/media/js/js_#.js") %>
</head>
T4MVC can also provide a way to reference the URL's:
<script src="<%= Links.Scripts.Map_js %>" type="text/javascript"></script>
Upvotes: 6
Reputation: 15835
you can give something like this during development , and so that it will show you the intellisens
<reference path="http://code.jquery.com/jquery-1.4.1.js"/>
Upvotes: 0