Microsoft ASP .NET MVC Framework is Microsoft’s implementation of the popular MVC pattern which was made popular for web applications chiefly by Ruby on Rails. The purpose of the framework is to give developers a choice over using ASP .NET webforms which, until the advent of the MVC framework, had been the only way to develop a web application with ASP .NET.
As with any new framework, especially the web, having a pattern for doing this is essential. Without a pattern developing an application that is clean and a codebase that properly leverages reusability of code in very difficult to do. One of the popular patterns for MVC is the ViewModel pattern. In this entry I will talk about developing an application that users this pattern and also explain why we make the decisions we do in developing the application so that we follow this pattern:
As you can see I have mutated the default project and removed the Models folder and replaced it with the ViewModels folder. In this folder are the classes that I will be passing to my strongly typed views.
I have created two other projects for this solution that are both class libraries: AM.DataAccess and AM.Models.
This pattern follows some of the advice that I got from @sbohlen at the ASP .NET MVC Firestarter I attended on 10/3. His advice was that it is ok to use an ORM like the ADO .NET Entity Framework to generate your entities but you should not pass them to the View. The reason for this makes sense because the generated entities come with a lot of “extra” functionality. This extra functionality is great in data access scenarios, but really do not make sense in the view.
This is why the ADO .NET Entities are in their own separate project. The Service classes in the DataAccess project are responsible for the translation of these generated entities to the entities that will be used by the view models.
This is simply a query that talks to the database via the EntityContext and takes the results and makes a List of these SeriesEntity objects. This list is then passed to my Controller. Once the controller receives it it then creates the necessary ViewModel class to be passed to the View, this is an example of such a piece of code:
The advantages of this model is the isolation of the generated entities with the entities designed for the web. This can reduce the amount of data sent across the wire and decreasing load size. In addition, there entities are more readily serialized into JSON results by MVC. The key thing to keep in mind is the separation of the Web from the Model layer, the two should never cross.
However, a disadvantage with using the Entity Framework in this way is the management of the context object (EntityContext in the example code). The way I have this setup is a lazy loaded property in a base class. The base class also has a destructor which disposes of the EntityContext. It doesn’t permit the sharing of the context by the request. This means you have as many EntityContext references as the number of Service instances that you have. Generally the best way to handle this problem is to use something like StrucutreMap or Ninject for Dependency Injection, however, that conversation is outside the scope of this post.
The main goal of this pattern is to provide a very clean and lightweight means to get data from a database and pass it to the view while maintaining type safety and leveraging code reuse. For example, the ViewModel classes can inherit from each other, like such. First this is the base class for all the ViewModel classes that are in use within this application:
So this base class defines a couple properties that will be in use on just about every page. (Side note: The validation in use here is called FluentValidation). Now lets look at the next level, the SeriesViewModel class:
(Note: CheckboxItem is a custom class that I created) Notice what we have available to us now in the View. We have two properties that can tie into existing MVC HtmlHelper methods to provide us with select boxes or a set of Checkboxes.
In conclusion, the ViewModel pattern is a very popular pattern among MVC developers because it reduces clutter in the controller and views, which is what the essence of MVC is: reduction of code and simplification of responsibilities. Furthermore, using ViewModel allows you to share and reuse code across multiple view and can truly make your View agnostic from the controller. This was one of the main weaknesses of the MVP pattern used by ASP .NET, the controller (code behind) was very tightly tied to the ASPX view.