Posts
201
Comments
1110
Trackbacks
51
February 2010 Entries
Create Your Own Code Snippets in Visual Studio 2010 for MVC 2

One of the great new features in Visual Studio 2010 is the ability to now use code snippets inside of ASP.NET, HTML, and JavaScript files. Snippets have long been a productivity boost for regular C# code but have been sorely missing for mark up. In fact, frameworks like MVC 2 actually ship with their own snippets.

 

There are only about 10-15 snippets that are currently shipping with MVC (and many of those are just duplicated because there are both VB and C# versions).  That doesn’t seem like very many.  But let’s have a look at one that would be pretty common – the HTML helper for a text box:

That snippet produces the following code:

   1:  <%= Html.TextBox("FirstName") %>

Hmmm. That code doesn’t seem very “MVC2ish”.  First off, it’s using the old school double-quoted string to specify the property rather than the new strongly-typed lambda-based HTML helper. Secondly, it’s using the TextBox() method rather than the EditorFor() method.  Third, it’s using the old <%= syntax which Microsoft is trying to get us to forget exists, rather than the new <%: HTML encoding syntax.

The best approach here is for us to create our own snippets customized to our heart’s content. But the snippet files are not the easiest things to work with so rather than starting from scratch, let’s just grab the MVC textbox snippet and modify it. The snippets can be found in the directory: C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 2\Visual Studio 2010\Snippets\HTML\1033\ASP.NET MVC 2. I’m going to grab the “textboxmvc.snippet” file from there, create a directory called “My MVC2 Snippets” and put it inside of the normal code snippets directory structure for Visual Studio. So the full path will be: <My Documents>\Visual Studio 2010\Code Snippets\Visual Web Developer\My MVC2 Snippets. Then I’ll rename “textboxmvc.snippet” to “editorfor.snippet”.

In order to get Visual Studio to recognize this location, I need to do Tools –> Code Snippet Manager and select the directory:

Next I’ll open the editorfor.snippet file in any code editor and change a few key lines:

   1:  <CodeSnippet Format="1.1.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
   2:    <Header>
   3:      <Title>editorfor</Title>
   4:      <Author>Steve Michelotti</Author>
   5:      <Shortcut>editorfor</Shortcut>
   6:      <Description>Markup snippet for an ASP.NET MVC EditorFor helper</Description>
   7:      <SnippetTypes>
   8:        <SnippetType>Expansion</SnippetType>
   9:      </SnippetTypes>
  10:      <ProjectTypeGuids>{F85E285D-A4E0-4152-9332-AB1D724D3325}</ProjectTypeGuids>
  11:    </Header>
  12:    <Snippet>
  13:      <Declarations>
  14:        <Literal>
  15:          <ID>property</ID>
  16:          <ToolTip>property</ToolTip>
  17:          <Default>property</Default>
  18:        </Literal>
  19:      </Declarations>
  20:      <Code Language="html" Key="*"><![CDATA[<%: Html.EditorFor(m => m$property$) %>$end$]]></Code>
  21:    </Snippet>
  22:  </CodeSnippet>

Line 3, 4, 5, and 6 are simple and straight-forward replacements.  The primary line I need to change is line 20. I’m going to use the generic “m” (for “Model”) for my lambda identifier and then use a replacement variable called $property$ (which I also specify on lines 15-17). I intentionally left out the “.” because after the snippet expands, I want the next keystroke I press to be the “.” so that intellisense will naturally come up for me (this snippet can be expanded without the mouse by typing “<edi”):

 

Just hit <Enter> and you’re all done!

Snippets are an area that you should absolutely leverage to take care of your most common mundane coding tasks and customize them per your own personal preferences/standards. Historically, my tool of choice for editing/creating snippet files is Snippy (though this doesn’t appear to actively be under development any more). I’ve also used Snippet Designer which has nice integration with Visual Studio. It appears that neither of these tools (yet) have support for the new language=”html” that is new in VS2010 (hopefully will support soon).

Posted On Tuesday, February 16, 2010 2:00 AM | Comments (1)
MVC 2 Editor Template with DateTime

One of the cool new features of MVC 2 is the ability to automatically pick an editor template based on the meta data of each property. This meta data can be as simple as the data type of the property itself.  Take an example where we have a Contact object that has a DateTime? property for DateOfBirth.

   1:  public partial class Contact
   2:  {
   3:      [DisplayName("First Name")]
   4:      public string FirstName { get; set; }
   5:   
   6:      [DisplayName("Last Name")]
   7:      public string LastName { get; set; }
   8:   
   9:      [DisplayName("Date of Birth")]
  10:      public DateTime? DateOfBirth { get; set; }
  11:  }

We can then display the property using markup like this:

   1:  <%=Html.LabelFor(m => m.Contact.DateOfBirth) %>
   2:  <%=Html.EditorFor(m => m.Contact.DateOfBirth)%>

This results in a view that looks something like this:

This is ugly.  It’s not user friendly for the user to have to type this and in many cases (like date of birth) we don’t care about the time portion – only the date.  With MVC 2 we can now, by convention, change the display for all of our DateTime data types just by adding a partial view called “DateTime.ascx” to a well-known folder called “EditorTemplates”:

Notice the EditorTemplates folder is in the Shared folder of views but you could scope this to a specific view folder as well. Now I can add my own partial view for DateTime. In fact, this will work for a nullable DateTime as well:

   1:  <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %>
   2:  <%=Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { @class = "datePicker" }) %>

The aspect that I *really* like about this functionality is the rendered HTML:

   1:  <input class="datePicker" id="Contact_DateOfBirth" name="Contact.DateOfBirth" type="text" value="4/1/1975" />

Notice how that “id” and “name” attributes were still correctly set despite that fact this this was in a partial view where we were just referring to the “Value” property of a nullable DateTime. This would have been tricky to do just using partial views with MVC 1 but here the framework is taking care of this for me. This means that the model binders will “just work” when the form is posted.

Another thing to note is that I’ve added a class attribute of “datePicker” because I’m using the jQuery datepicker to give a nice little calendar UI for the end user.

   1:  <script src="../../Scripts/jquery-datepicker.js" type="text/javascript"></script>
   2:  <script type="text/javascript">
   3:      $(function() {
   4:          $(".datePicker").datepicker({ showOn: 'both', buttonImage: "/images/calendar.gif" });
   5:      });
   6:  </script>

This gives a much nicer user experience:

MVC 2 editors result in a much nicer development experience. My call to the EditorFor() HTML helper method remains unchanged. But rather than just rendering a simple HTML text box with no formatting of the DateTime, it will now automatically pick up my DateTime editor template for ALL my DateTime properties and show a nice UI with better formatting.  Also note that if you have a date time that is an exception to this and you want to display a different editor, you can still use the [UIHint] attribute to control the meta data and therefore select a different editor for a DateTime.

Posted On Friday, February 5, 2010 4:26 AM | Comments (58)

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

Tag Cloud