Wednesday, April 18, 2012

VS2010: Using javascript intellisense for third party javascript libraries with MVC razor

I have been spending a ton of time learning MVC3 of late. Its great how well the framework has been designed to work hand in hand with jQuery with respect to unobtrusive client side validation. Obviously one of the things that makes Visual studio (or any decent IDE for that matter) great for any .net developer, is the awesome intellisense support. However I ran into a tiny snag while trying to get visual studio to render any intellisense for jquery. Let me demonstrate using the example below:
Assume I have the following _Layout.cshtml file:

   1:  <!DOCTYPE html>
   2:  <html>
   3:  <head>
   4:      <meta charset="utf-8" />
   5:      <title>@ViewBag.Title</title>
   6:      <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
   7:     <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
   8:      <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
   9:  </head>
  11:  <body>
  12:      @RenderBody()
  13:  </body>
  14:  </html>

ok great I have all my jquery libraries defined and now I am ready to create MVC views that will utilize this layout. Here's a partial excerpt from a simple view ~/Home/Sample.cshtml that utilizes the above layout page:
   1:  @{
   2:      ViewBag.Title = "Sample";
   3:  }
   5:  <h2>Sample</h2>
   7:  <script type="text/javascript">
   8:      $(document).
   9:  </script>
  12:  @using(Html.BeginForm())
  13:  {
  14:      @:Enter your name: @Html.TextBox("name")
  15:      <input type="submit" value='Submit Name'/>
  16:  }
As you do, my view is laden with common html script mixed with some mvc3 razor syntax. Now notice how in line 8 I have begun using a jquery selector on the JS document object. One would assume that one hit of the compile project button should automatically warrant visual studio to render all sorts of jquery related intellisense. Nope, that does not happen. And quite frankly I assumed that wouldn't work. If you think about it, in the context of editing the view, VS cannot work out during design time which layout file this view is going to use. Of course there could be some awesome “behind the scenes” code to automatically work this out based on the layout set in the _ViewStart.cshtml file but perhaps this is something for the future (hint hint).

A bit of googling pointed out what I had suspected all along. Visual studio does not have a notion of all the scripts that will be loaded client side for this view (account for the existence of mvc partial views as well). Turns out, if you want to use javascript intellisense feature for any third party scripts, then you need to manually reference the jquery Visual studio 2010 intellisense documentation script file into every view that you work like so:
   1:  @{
   2:      ViewBag.Title = "Sample";
   3:  }
   5:  <h2>Sample</h2>
   7:  @if (false)
   8:  {
   9:      <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.7.1-vsdoc.js")"></script>
  10:  }
  12:  <script type="text/javascript">
  13:      $(document).
  14:  </script>
  17:  @using (Html.BeginForm())
  18:  {
  19:      @:Enter your name: @Html.TextBox("name")
  20:      <input type="submit" value='Submit Name'/>
  21:  }

Couple of things to note here. Lines 7-10 show a javascript node referencing the the jquery-1.7.1-vsdoc.js encapsulated inside a razor if statement. This contains VS2010 specific vsdoc that aides visual studio’s intellisense. Since we are already referencing the core jquery libraries in our _Layout.cshtml file, having clients download this script every time this view is rendered as part of a request is unnecessary. Hence having the if block always evaluate to false ensures that this script element never gets rendered as part of a HTTP response. However even though we now have our reference, visual studio still does not render any JS intellisense for my jquery selector (line 13). As part of my orientation with the MVC framework, I have become accustomed to using the plethora of awesome MVC helper functions within my views to generate url’s, action-links, forms etc. We use the Url.Content helper to generate our jquery script reference in line 9. An unfortunate trade –off with this is that visual studio cannot seem to work out the script reference path during design time. The only remedy to this is to hard code a relative path to the script in line-9 of the Sample.cshtml view like so:

<script type="text/javascript" src="../../Scripts/jquery-1.7.1-vsdoc.js"></script>

This does the trick and enables jquery intellisense. I hate having to hardcode the script reference but I guess as long as we ensure that this reference is never included as part of the response, its a small price to pay for having intellisense enabled. I hope the ASP.Net team sort this out soon
Technorati Tags: ,,,,,