Posts
203
Comments
1120
Trackbacks
51
October 2009 Entries
ASP.NET MVC View Model Patterns

Since MVC has been released I have observed much confusion about how best to construct view models. Sometimes this confusion is not without good reason since there does not seem to be a ton of information out there on best practice recommendations.  Additionally, there is not a “one size fits all” solution that acts as the silver bullet. In this post, I’ll describe a few of the main patterns that have emerged and the pros/cons of each. It is important to note that many of these patterns have emerged from people solving real-world issues.

Another key point to recognize is that the question of how best to construct view models is *not* unique to the MVC framework.  The fact is that even in traditional ASP.NET web forms you have the same issues.  The difference is that historically developers haven’t always dealt with it directly in web forms – instead what often happens is that the code-behind files end up as monolithic dumping grounds for code that has no separation of concerns whatsoever and is wiring up view models, performing presentation logic, performing business logic, data access code, and who knows what else.  MVC at least facilitates the developer taking a closer look at how to more elegantly implement Separation of Concerns.

Pattern 1 – Domain model object used directly as the view model

Consider a domain model that looks like this:

   1:  public class Motorcycle
   2:  {
   3:      public string Make { get; set; }
   4:      public string Model { get; set; }
   5:      public int Year { get; set; }
   6:      public string VIN { get; set; }
   7:  }

When we pass this into the view, it of course allows us to write simple HTML helpers in the style of our choosing:

   1:  <%=Html.TextBox("Make") %>
   2:  <%=Html.TextBoxFor(m => m.Make) %>

And of course with default model binding we are able to pass that back to the controller when the form is posted:

   1:  public ActionResult Save(Motorcycle motorcycle)

While this first pattern is simple and clean and elegant, it breaks down fairly quickly for anything but the most trivial views. We are binding directly to our domain model in this instance – this often is not sufficient for fully displaying a view.

Pattern 2 – Dedicated view model that *contains* the domain model object

Staying with the Motorcycle example above, a much more real-world example is that our view needs more than just a Motorcycle object to display properly.  For example, the Make and Model will probably be populated from drop down lists. Therefore, a common pattern is to introduce a view model that acts as a container for all objects that our view requires in order to render properly:

   1:  public class MotorcycleViewModel
   2:  {
   3:      public Motorcycle Motorcycle { get; set; }
   4:      public SelectList MakeList { get; set; }
   5:      public SelectList ModelList { get; set; }
   6:  }

In this instance, the controller is typically responsible for making sure MotorcycleViewModel is correctly populated from the appropriate data in the repositories (e.g., getting the Motorcycle from the database, getting the collections of Makes/Models from the database).  Our Html Helpers change slightly because they refer to Motorcycle.Make rather than Make directly:

   1:  <%=Html.DropDownListFor(m => m.Motorcycle.Make, Model.MakeList) %>

When the form is posted, we are still able to have a strongly-typed Save() method:

   1:  public ActionResult Save([Bind(Prefix = "Motorcycle")]Motorcycle motorcycle)

Note that in this instance we had to use the Bind attribute designating “Motorcycle” as the prefix to the HTML elements we were interested in (i.e., the ones that made up the Motorcycle object).

This pattern is simple and elegant and appropriate in many situations. However, as views become more complicated, it also starts to break down since there is often an impedance mismatch between domain model objects and view model objects.

 

Pattern 3 – Dedicated view model that contains a custom view model entity

As views get more complicated it is often difficult to keep the domain model object in sync with concerns of the views.  In keeping with the example above, suppose we had requirements where we need to present the user a checkbox at the end of the screen if they want to add another motorcycle.  When the form is posted, the controller needs to make a determination based on this value to determine which view to show next. The last thing we want to do is to add this property to our domain model since this is strictly a presentation concern. Instead we can create a custom “view model entity” instead of passing the actual Motorcycle domain model object into the view. We’ll call it MotorcycleData:

   1:  public class MotorcycleData
   2:  {
   3:      public string Make { get; set; }
   4:      public string Model { get; set; }
   5:      public int Year { get; set; }
   6:      public string VIN { get; set; }
   7:      public bool AddAdditionalCycle { get; set; }
   8:  }

This pattern requires more work and it also requires a “mapping” translation layer to map back and forth between the Motorcycle and MotorcycleData objects but it is often well worth the effort as views get more complex.  This pattern is strongly advocated by the authors of MVC in Action (a book a highly recommend).  These ideas are further expanded in a post by Jimmy Bogard (one of the co-authors) in his post How we do MVC – View Models. I strongly recommended reading Bogard’s post (there are many interesting comments on that post as well). In it he discusses approaches to handling this pattern including using MVC Action filters and AutoMapper (I also recommend checking out AutoMapper).

Let’s continue to build out this pattern without the use of Action filters as an alternative. In real-world scenarios, these view models can get complex fast.  Not only do we need to map the data from Motorcycle to MotorcycleData, but we also might have numerous collections that need to be populated for dropdown lists, etc.  If we put all of this code in the controller, then the controller will quickly end up with a lot of code dedicated just to building the view model which is not desirable as we want to keep our controllers thin. Therefore, we can introduce a “builder” class that is concerned with building the view model.

   1:  public class MotorcycleViewModelBuilder
   2:  {
   3:      private IMotorcycleRepository motorcycleRepository;
   4:   
   5:      public MotorcycleViewModelBuilder(IMotorcycleRepository repository)
   6:      {
   7:          this.motorcycleRepository = repository;
   8:      }
   9:   
  10:      public MotorcycleViewModel Build()
  11:      {
  12:          // code here to fully build the view model 
  13:          // with methods in the repository
  14:      }
  15:  }

This allows our controller code to look something like this:

   1:  public ActionResult Edit(int id)
   2:  {
   3:      var viewModelBuilder = new MotorcycleViewModelBuilder(this.motorcycleRepository);
   4:      var motorcycleViewModel = viewModelBuilder.Build();
   5:      return this.View();
   6:  }

Our views can look pretty much the same as pattern #2 but now we have the comfort of knowing that we’re only passing in the data to the view that we need – no more, no less.  When the form is posted back, our controller’s Save() method can now look something like this:

   1:  public ActionResult Save([Bind(Prefix = "Motorcycle")]MotorcycleData motorcycleData)
   2:  {
   3:      var mapper = new MotorcycleMapper(motorcycleData);
   4:      Motorcycle motorcycle = mapper.Map();
   5:      this.motorcycleRepository.Save(motorcycle);
   6:      return this.RedirectToAction("Index");
   7:  }

Conceptually, this implementation is very similar to Bogard’s post but without the AutoMap attribute.  The AutoMap attribute allows us to keep some of this code out of the controller which can be quite nice.  One advantage to not using it is that the code inside the controller class is more obvious and explicit.  Additionally, our builder and mapper classes might need to build the objects from multiple sources and repositories. Internally in our mapper classes, you can still make great use of tools like AutoMapper.

In many complex real-world cases, some variation of pattern #3 is the best choice as it affords the most flexibility to the developer.

 

Considerations

How do you determine the best approach to take?  Here are some considerations to keep in mind:

Code Re-use – Certainly patterns #1 and #2 lend themselves best to code re-use as you are binding your views directly to your domain model objects. This leads to increased code brevity as mapping layers are not required. However, if your view concerns differ from your domain model (which they often will) options #1 and #2 begin to break down.

Impedance mismatch – Often there is an impedance mismatch between your domain model and the concerns of your view.  In these cases, option #3 gives the most flexibility.

Mapping Layer – If custom view entities are used as in option #3, you must ensure you establish a pattern for a mapping layer. Although this means more code that must be written, it gives the most flexibility and there are libraries available such as AutoMapper that make this easier to implement.

Validation – Although there are many ways to perform validation, one of the most common is to use libraries like Data Annotations. Although typical validations (e.g., required fields, etc.) will probably be the same between your domain models and your views, not all validation will always match.  Additionally, you may not always be in control of your domain models (e.g., in some enterprises the domain models are exposed via services that UI developers simply consume).  So there is a limit to how you can associate validations with those classes.  Yes, you can use a separate “meta data” class to designate validations but this duplicates some code similar to how a view model entity from option #3 would anyway. Therefore, option #3 gives you the absolute most control over UI validation.

 

Conclusion

The following has been a summary of several of the patterns that have emerged in dealing with view models. Although these have all been in the context of ASP.NET MVC, the problem with how best to deal with view models is also an issue with other frameworks like web forms as well. If you are able to bind directly to domain model in simple cases, that is the simplest and easiest solution. However, as your complexity grows, having distinct view models gives you the most overall flexibility.

Posted On Sunday, October 25, 2009 9:03 AM | Comments (60)
Setting Selected Item in FluentHtml Select List

I ran into a small issue today when using the FluentHtml Select() HtmlHelper.  My original code was not properly setting the value of the selected item in the drop down:

<%=this.Select(m => m.Motorcycle.Make).Selected(Model.Motorcycle.Make).Label("Vehicle Make").Options(Model.MakeList)%>

I kept ending up with no item being selected from the drop down even though I definitely had a vehicle Make populated in my model and my drop down was correctly populated with the collection from the “MakeList” property of the view model.  It turns out that the solution was a simple matter of corrected ordering:

<%=this.Select(m => m.Motorcycle.Make).Options(Model.MakeList).Selected(Model.Motorcycle.Make).Label("Vehicle Make")%>

In hindsight I guess this order makes a little more sense intuitively anyway.  However, the fluent API did not constrain me from running into this issue.  So, just a heads up, when using the Select() helper, set the Options() first, and then set the selected value by invoking the Selected() helper method.

Posted On Thursday, October 22, 2009 2:30 PM | Comments (4)
StructureMap with Named Instance and With Method

I ran into an interesting IoC issue today that was ultimately resolved by some extremely helpful email assistance by Chad Myers. I’ll post the solution here in the hopes that someone else will find it helpful. Here is the code to set up the example:

   1:  public interface IFoo
   2:  {
   3:      IBar Bar { get; set; }
   4:  }
   5:   
   6:  public class Foo : IFoo
   7:  {
   8:      public IBar Bar { get; set; }
   9:   
  10:      public Foo(IBar bar)
  11:      {
  12:          this.Bar = bar;
  13:      }
  14:  }
  15:   
  16:  public interface IBar
  17:  {
  18:      bool Flag { get; set; }
  19:  }
  20:   
  21:  public class Bar : IBar
  22:  {
  23:      public bool Flag { get; set; }
  24:   
  25:      public Bar(bool flag)
  26:      {
  27:          this.Flag = flag;
  28:      }
  29:  }

The key here is that Bar has a constructor that takes a Boolean parameter and there are some circumstances where I want Bar to have a true parameters and some instances where I want it to be false.  Because of this variability, I can’t just initialize like this:

   1:  x.ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>().WithCtorArg("flag").EqualTo(true);

That won’t work because that only supports the “true” parameter for IBar. In order to support both, I need to utilize named instances.  Therefore, my complete StructureMapBootstrapper looks like this:

   1:  public static class StructureMapBootstrapper
   2:  {
   3:      public static void Initialize()
   4:      {
   5:          ObjectFactory.Initialize(x =>
   6:              {
   7:                  x.ForRequestedType<IFoo>().TheDefaultIsConcreteType<Foo>();
   8:                  x.ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>().WithCtorArg("flag").EqualTo(true).WithName("TrueBar");
   9:                  x.ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>().WithCtorArg("flag").EqualTo(false).WithName("FalseBar");
  10:              });
  11:      }
  12:  }

This now enables me to create instances of IBar by using the GetNamedInstance() method.  However, the primary issue is that I need to create an instance of IFoo and Foo has a nested dependency on IBar (where the parameter can vary).  It turns out the missing piece to the puzzle is to simply leverage the ObjectFactory’s With() method (in conjunction with the GetNamedInstance() method) which takes an object instance and returns an ExplicitArgsExpression to enable the fluent syntax. Therefore, these instances can easily be instantiated either way like this:

   1:  var fooWithTrueBar = ObjectFactory.With(ObjectFactory.GetNamedInstance<IBar>("TrueBar")).GetInstance<IFoo>();
   2:  var fooWithFalseBar = ObjectFactory.With(ObjectFactory.GetNamedInstance<IBar>("FalseBar")).GetInstance<IFoo>();

Just another example of how IoC containers can enable us to keep clean separation of concerns in our classes and enable us to avoid cluttering our code with the wiring up of dependencies.

Posted On Wednesday, October 14, 2009 11:07 PM | Comments (5)
What IoC Container do you use?

I often get asked what IoC Container I prefer.  Short answer: StructureMap. I love the fluent syntax for configuration. Overall, it’s easy to use, has many advanced features, and is very lightweight.  I view the learning curve with StructureMap as relatively small.  It is one of the longest-lived IoC containers (if not *the* longest) and has a huge adoption rate which means it’s quite mature and not difficult to find code examples online. For example, there is the StructureMap mailing list. Additionally, the community is very proactive – I just sent an email question to Chad Myers today and got a response within minutes that solved my issue. The creator of StructureMap, Jeremy Miller, has one of the most useful blogs around (in addition to his column in MSDN magazine).

Despite all this, there are still several other very high quality IoC containers available including: Unity, Ninject, Windsor, Spring.NET, and AutoFac. Unity is Microsoft’s offering in the IoC space and often it gets picked simply because it’s got the “magical” Microsoft label on it.  In fact, some organizations (for better or worse – usually worse) have policies *against* using OSS software and your only choice is to look at the offerings on the Microsoft platform.  Despite this, Unity is actually pretty good but by P&P’s own admission, there are instances where StuctureMap implementation is a little more elegant than Unity. But Unity does still have some compelling reasons to use it. In fact, if you are already using the Microsoft Enterprise Library Application Blocks, choosing Unity makes sense for a little more seamless experience.

Having said all this, there is one other major caveat to my preference towards StructureMap – it’s the IoC tool I’m most familiar with. Therefore you should take a recommendation from me (or *anyone*) with a grain of salt.  Ultimately the features of the various IoC’s are going to be comparable and it’s the developer familiarity with that tool that is going to make the difference.  For folks new to IoC, most of the uses are going to be for simple constructor dependency injection and all the IoC frameworks can handle that easily.  Given the wealth of quality IoC frameworks, we need another IoC framework about as bad as we need another data access technology. :)

Posted On Wednesday, October 14, 2009 3:22 PM | Comments (2)
NoVa Code Camp – Code Samples

Thanks to everyone who attended my session today at NoVa Code Camp.  Both the code and PowerPoint slides are available for download.

Download samples for: MVC in the Real World. Check out the readme.txt file in Solution Items and all SQL scripts for creating the databases.

Posted On Saturday, October 10, 2009 3:30 PM | Comments (6)
NoVa Code Camp

This Saturday (October 10) I’ll be presenting at the NoVa Code CampRegistration is still open.

I will be presenting “MVC in the Real World”.  There are many great sessions on the schedule.  Hope to see you there!

Posted On Wednesday, October 7, 2009 3:44 PM | Comments (0)
Richmond Code Camp - Code Samples

Thanks to everyone who attended my sessions yesterday at Richmond Code Camp.  Both the code and PowerPoint slides are available for download.

Download samples for: MVC in the Real World. Check out the readme.txt file in Solution Items and all SQL scripts for creating the databases.

Download samples for: C# 4.0 New Language Features.

I had several questions about some of the tools I was using during the presentations (all of which are free).  For the zooming and highlighting, I was using a tool called ZoomIt. For the code snippets, I was just utilizing the built-in code snippets functionality of Visual Studio – however, I use a tool called Snippy to create all of my custom snippets. You can find links to those tools and many other tools I use on my Developer Tools and Utilities post.

Posted On Sunday, October 4, 2009 4:11 PM | Comments (3)
MVP

I just found out today that I was awarded the MVP designation from Microsoft in the area of ASP.NET. It has been a very busy 2009 for me, speaking at various user groups and code camps including CMAP, CapArea, RockNUG, SoMDNUG, FredNUG, and Richmond Code Camp.  I would like to thank all of those user groups for having me present and I look forward to continuing my involvement with all of those user groups and more in the year to come.

With .NET 4.0 and the 2010 wave just around the corner, the upcoming year looks to bring some exciting enhancements in numerous areas including MVC, WCF REST, C# 4.0, Dublin, and the .NET framework in general.

Posted On Thursday, October 1, 2009 3:21 AM | 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