Managing Models in ASP.NET MVC
Peter Vogel looks at the least important component of the ASP.NET MVC, the Model, and goes on to discuss a strategy for integrating the model, the controller and the view.
One of the key design criteria for a controller is that it have no business logic and no display logic. The controller has two (and only two) responsibilities: Pick the View and gather the data from the model and pass it to the View. The View's responsibility is to display the data to the user and gather the user's input.
So the model does everything else: moving data in an out of the database, handling business rules, and more. However, in an ASP.NET MVC application, it's the least important component because the model has the least to do with the Web application. A controller should be able to work with any model and it should be possible to plug any model into an ASP.NET MVC controller. As with the business objects accessed by an ASP.NET application, there are no requirements imposed on the model's objects (unlike an ASP.NET MVC controller which must, for instance, implement the IController interface and follow a specific naming convention).
That doesn't mean that there aren't some things to consider when building an ASP.NET MVC application.
When it comes to the business layer, my first inclination these days is to use Entity Framework and extend the entities that it returns with Partial Classes. The next obvious step is to use WCF Services (as I discussed in an earlier column in conjunction with AJAX). A controller could call a WCF service and receive a business entity in return which the controller could then pass onto the View. This would work very well, for instance, for a page or form that supports maintaining a lookup table.
However, a view is the application's user interface and is going to need to support the user's workflow -- not the application's object model or the application's relational table design. Most UIs combine several business entities (think, for instance, of a sales order page that would have information from a sales order, its individual lines, customer information and product information). A typical controller would need to make several calls to its services to retrieve the necessary business objects to assemble the data for a view.
The second slowest thing that you can do in data processing is to make a call to another computer (the first slowest thing is to read or write to your hard disk). If the layers that make up your application are going to be separated over multiple computers, then the most likely separations are between your data access layer and between the controller and the service layer. Even if your connector is connected to the services that provide data with remoting instead of with Web services (and both options are available in WCF), you'll still take a hit with every call you make to another computer.
That being the case, you'll want to reduce your calls to the service providing your data to the minimum number: one. To do that, your model will have to be responsible for not only retrieving and updating the data but also for assembling and disassembling the data transfer objects that will move data between the model and the controller. Since the controller can pass any object to the view (see my previous column, Viewing Views in ASP.NET MVC) the controller can be reduced to making a call to the service, retrieving a data transfer object, and passing it to the view.
The result: Not only is your view terrifically simple so is your controller. Your development and testing efforts can concentrate on your model.
Peter Vogel is a principal in PH&V Information Services, specializing in ASP.NET development with expertise in SOA, XML, database, and user interface design. His most recent book ("rtfm*") is on writing effective user manuals, and his blog on technical writing can be found at rtfmphvis.blogspot.com.