Posts
202
Comments
1112
Trackbacks
51
January 2010 Entries
.NET 4.0 and Visual Studio 2010 Presentation at Microsoft

On February 4th, I will be presenting .NET 4.0 and Visual Studio 2010 at the Microsoft office in Reston as part of my company’s continued efforts to provide education on Microsoft technologies. This presentation will cover a wide breadth of technologies that are being launched by Microsoft this year. The presentation is geared towards technical decision makers including Architects, CTO, CIO, Project Managers, IT Managers, and senior development resources. This a totally free Microsoft sponsored event that is intended to provide a solid foundation on the vast landscape of technologies being released and how best they can be leveraged in your organization.  The topics will include:

  • .NET Framework 4 enhancements
  • Visual Studio 2010
  • Parallel Extensions
  • C# 4.0 & VB10 language enhancements
  • ASP.NET 4
  • Microsoft AJAX Library
  • MVC 2
  • Entity Framework 4
  • WCF Data Services
  • WCF 4 & REST
  • Workflow Foundation 4
  • AppFabric
  • AppFabric Caching
  • Silverlight

This event is free and you can register here. Hope to see you there.

Posted On Friday, January 22, 2010 1:08 PM | Comments (0)
Encapsulate Multiple HTML Helpers to Make Views More DRY

MVC 2 is adding many new features that make views more elegant to write. For example, the new EditorFor() Html helper returns the appropriate HTML input elements for a given property so you don’t have to explicitly specify text box, dropdown, or whatever control you need and can even use the [UIHint] attribute to specify the editor you want to use (either an OOTB or custom editor). This results in view markup that often looks like this:

   1:  <p>
   2:      <%=Html.LabelFor(m => m.FirstName)%>
   3:      <%=Html.EditorFor(m => m.FirstName)%>
   4:      <%=Html.ValidationMessageFor(m => m.FirstName)%>
   5:  </p>
   6:  <p>
   7:      <%=Html.LabelFor(m => m.LastName)%>
   8:      <%=Html.EditorFor(m => m.LastName)%>
   9:      <%=Html.ValidationMessageFor(m => m.LastName)%>
  10:  </p>

This allows us to simply use attributes to specify meta-data on our view models like this:

   1:  public class Person
   2:  {
   3:      [DisplayName("First Name")]
   4:      [Required(ErrorMessage = "First Name is required.")]
   5:      [StringLength(50, ErrorMessage = "Last name must be less than 50 characters.")]
   6:      public string FirstName { get; set; }
   7:   
   8:      [DisplayName("Last Name")]
   9:      [Required(ErrorMessage = "Last Name is required.")]
  10:      [StringLength(50, ErrorMessage = "Last name must be less than 50 characters.")]
  11:      public string LastName { get; set; }
  12:  }

For example, the [DisplayName] attribute used on line #3 and line #8 above will be honored by the LabelFor() html helper method. This new functionality of MVC 2 has been blogged about quite a bit to date and provides great improvements over MVC 1. In summary these improvements are:

  • Display Names with LabelFor() – Ability to specify display name on our view models meta data and not have to worry about specifying it in the views.
  • HTML input with EditorFor() - Ability to simply use EditorFor() in the view and allow MVC to pick the appropriate editor either automatically or by honoring the [UIHint] attribute as part of meta data in our view models.
  • Validation with ValidationFor() - Ability for the validation to honor DataAnnotations attributes and have this all “baked in” including the actual validation execution itself (including client-side valdiation).

While this is not an exhaustive list for the improvements in MVC 2, the common theme in all this is that, in the most typical cases, each view model property has 3 components: 1) the label, 2) the editor, and 3) validation.  Looking at the first code sample above, I’m calling the same three HTML helper methods for every view model property (i.e., LabelFor(), EditorFor(), and ValidationMessageFor()). The only thing different between them is the view model property being used for the lambda expressions.  For a single property, the same lambda expression is being used for all three HTML helpers. This doesn’t make our views very DRY. If we were doing this sort of thing in C#, we’d create a method to encapsulate the repetition and there’s no reason we shouldn’t do same thing for the code in our views. Therefore, we can create a simple HTML helper that encapsulates these like this:

   1:  public static MvcHtmlString ValidatedEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
   2:  {
   3:      var html =
   4:          htmlHelper.LabelFor(expression).ToString() +
   5:          htmlHelper.EditorFor(expression).ToString() +
   6:          htmlHelper.ValidationMessageFor(expression).ToString();
   7:   
   8:      return MvcHtmlString.Create(html);
   9:  }

This allows us to now change our original view code to this while still maintaining the same HTML markup that is generated:

   1:  <p>
   2:      <%=Html.ValidatedEditorFor(m => m.FirstName)%>
   3:  </p>
   4:  <p>
   5:      <%=Html.ValidatedEditorFor(m => m.LastName)%>
   6:  </p>

Also, if you’re using MVC 2 with ASP.NET 4 instead of ASP.NET 3.5, you can take advantage of the new <%: %> syntax rather than the old <%= %> syntax.

   1:  <p>
   2:      <%:Html.ValidatedEditorFor(m => m.FirstName)%>
   3:  </p>
   4:  <p>
   5:      <%:Html.ValidatedEditorFor(m => m.LastName)%>
   6:  </p>

Now the views are *extremely* simple and with a single HTML helper we’ll automatically get a label, an editor, and validation. Also notice that the HTML helper is using MvcHtmlString rather than just a string as all HTML helpers in MVC 2 are now HTML encoded by default.

The snippet above is only showing two view model properties but if your view has 10, 20, or even 100 or more properties, the difference becomes even more dramatic since the code is only one-third the size. Additionally, the trend you see is that more and more of your development paradigm is being moved away from the views and into your C# view models. This allows for dramatically cleaner/simpler views while also enabling the overall code base to be more testable and less error prone.

Posted On Sunday, January 17, 2010 12:52 PM | Comments (4)
Implementing a Delete Link with MVC 2 and HttpMethodOverride

A while back I blogged about creating an MVC Delete Link with the AjaxHelper. This was based on another blog post from Stephen Walther where he explained the drawbacks of using hyperlinks for delete scenarios.  HTTP and REST best practices state that GET requests should never modify a resource. The most “RESTful” implementation is is use a DELETE verb. In Walther’s post he shows two primary examples: 1) using AJAX to issue a true “DELETE” request, and 2) using individual forms to do the delete operations. In my previous post on MVC DeleteLink, I essentially showed a variation of his first example (i.e., the AJAX method). In this post I’ll show a variation on his second example using MVC 2 and the new HttpMethodOverride (i.e., using individual forms for the delete).

An HTML form supports only GET and POST for the form action. It does not support PUT or DELETE verbs. Hence, the typical solution to this is the leverage the form POST to do delete operations as well (in effect, “overloading” the meaning of form POST). MVC 2 introduces a new HTML helper called HttpMethodOverride which allows your form POST to “act like” another verb. This is a common convention that is used by other frameworks (Ruby on Rails does something similar) – sometimes passing “X-HTTP-Method-Override” in an HTTP header and sometimes passing it in a hidden form variable like this. Therefore, if we want a simple delete link, we can now do it like this:

   1:  <%Html.BeginForm("Delete", "Contacts", new { id = workout.Id }); %>
   2:      <input type="image" src="/images/remove-icon.png" alt="Delete" />
   3:      <%=Html.HttpMethodOverride(HttpVerbs.Delete) %>
   4:  <%Html.EndForm(); %>

This will render HTML output like this:

   1:  <form action="/Contacts/Delete/1" method="post">
   2:      <input type="image" src="/images/remove-icon.png" alt="Delete" />
   3:      <input name="X-HTTP-Method-Override" type="hidden" value="DELETE" />
   4:  </form>

The best part about this is the the MVC action method attributes will respect this form variable:

   1:  [HttpDelete]
   2:  public ActionResult Delete(int id)
   3:  {
   4:      this.repository.Delete(id);
   5:      return this.RedirectToAction("Index");
   6:  }

Notice the [HttpDelete] attribute. This is also new in MVC 2 as a more succinct version of [AcceptVerbs(HttpVerbs.Delete)]. This is a much better and cleaner implementation than we had available in MVC 1.  However, needing a delete link is something that is going to be pretty common in your applications and creating a form, an input tag and the HttpMethodOverride() is a lot to go through every time you need it. As always, the best approach to keep things simpler (and more DRY) is to create your own re-usable HTML helper method that will allow you to call it like this:

   1:  <%=Html.DeleteLink("Delete", "Workouts", new { id = workout.Id }, "/images/remove-icon.png") %>

The complete code for that HTML helper method:

   1:  public static MvcHtmlString DeleteLink(this HtmlHelper helper, string actionName, string controllerName, object routeValues, string imageUrlPath)
   2:  {
   3:      var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
   4:      var url = urlHelper.Action(actionName, controllerName, routeValues);
   5:   
   6:      var formTag = new TagBuilder("form");
   7:      formTag.MergeAttribute("action", url);
   8:      formTag.MergeAttribute("method", "post");
   9:   
  10:      var inputTag = new TagBuilder("input");
  11:      inputTag.MergeAttribute("type", "image");
  12:      inputTag.MergeAttribute("src", imageUrlPath);
  13:      inputTag.MergeAttribute("alt", "Delete");
  14:   
  15:      formTag.InnerHtml = inputTag.ToString(TagRenderMode.SelfClosing) + helper.HttpMethodOverride(HttpVerbs.Delete);
  16:   
  17:      return MvcHtmlString.Create(formTag.ToString());
  18:  }

Also notice this is returning the new MvcHtmlString type rather than just a string.

So does this allows us to be more “RESTful”? Yes, it does. But we could still go further.  I really like the approach by Dylan Beattie here in which he introduces route constraints so the URL’s don’t need to contain segments like “/Delete” or “/Edit”. His approach could be further generalized for *all* controllers such that any POST request that came in with and X-HTTP-Method-Override of “DELETE” would automatically be routed to an action method named Delete(). This is a convention that makes a lot of sense and could also be further enforced with a layer supertype controller.

Posted On Friday, January 8, 2010 11:57 PM | Comments (4)

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