Search code examples
javascriptasp.net-mvcmarkup

What is the best way to include script references in ASP.NET MVC views?


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.


Solution

  • 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.