Wednesday, March 17, 2010

Maintainable MVC: Binding

This article is part of the Maintainable MVC Series.



By using the form models as spoken about in View Model and Form Model the need for custom binding doesn't arise to often anymore.



But every now and then we have some duplicate code doing something with incoming parameters. Perhaps we can move this logic into a binder to be more DRY. Or if our form model has types that MVC can't bind automatically - like enumerations - custom binding comes into play.



MVC is extensible on the part of binding form data or get parameters to your method parameters. You can define your own binders and have them work for certain types.


Wednesday, March 10, 2010

Maintainable MVC: Post-Redirect-Get pattern

This article is part of the Maintainable MVC Series.



It keeps amazing me that every time I see some example MVC code from Scott Guthrie, Phil Haack or one of our other MVC heroes, it keeps looking like this:



[csharp highlight="10"]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(BlogItem blogItem)
{
if (ModelState.IsValid)
{
...
return RedirectToAction("OtherAction");
}

return View(blogItem);
}
[/csharp]

The big problem with this code is that it returns a view (on the highlighted line), while the method handles a POST. It seems like a very bad practice, because it disrupts the natural flow of your website. It makes it impossible to make use of your browser history (the back button) without running into a 'this page is expired' warning. Or your user could post the same data multiple times.



It is an annoyance which will definitely cost your website some visitors! So no more return View in a post method!


Monday, March 08, 2010

Maintainable MVC Series: Poor man’s RenderAction

This article is part of the Maintainable MVC Series.



Soon - once that MVC 2 is finalized and released - we will have access to the new Html.Action command with which we can easily render partials for shared functionality, like navigation structure or other parts of the master page that need dynamic data. As Phil Haack shows in this post it's a very powerful and urgently needed feature.

In the master view you will have a call like this:



[csharp light="true"]

<%= Html.Action("Menu") %>

[/csharp]

This will directly call a method in one of your controllers to supply the partial view with its data:



[csharp]
[ChildActionOnly]
public ActionResult Menu() {

NavigationData navigationData = navigationService.GetNavigationData();
MenuViewModel menuViewModel = mapper.GetMenuViewModel(navigationData);

return PartialView(menuViewModel);
}
[/csharp]

Unfortunately in MVC 1 we have to make use of a more elaborate trick to get the data to the partial view.


Wednesday, March 03, 2010

Maintainable MVC Series: View Model and Form Model

This article is part of the Maintainable MVC Series.



As mentioned in the previous post all views are strongly typed and every view has it's own View Model. Although this results in quite a lot of classes the upside is maintainability in that it's very straightforward. Every bit of data displayed in the view has a corresponding property in the View Model. As soon as it's no longer needed in the view we remove the property as well.



Of course, it sounds like it's in opposition with the DRY principle (Don't Repeat Yourself). However the data in the properties of the view models stems from the domain model, meaning the business rules are still in one place. To get the data from the domain model to the view models we have mapper classes in the presentation layer.


Wednesday, February 24, 2010

Maintainable MVC Series: View hierarchy

This article is part of the Maintainable MVC Series.


The view system of ASP.NET MVC knows the followings types of views:



  • Master views

  • Page views

  • Partial views


The regular page view contains the specific html and presentation of data for each rendered page. For html shared by multiple pages - like navigation, header and footer - every page has a master page.


Both of these types can include partial views for small parts, that can be reused from multiple views. For example page navigation for display of results covering multiple pages, or widgets. Even if they're not reused it is useful to separate parts of your page view or master view to partial views, to keep the (master) view itself comprehensible and maintainable.


For using partial views in the master view we have a special way to provide them with data (which is sometimes specific to the page requested, like which menu item is active). This is explained in the future part Poor Man's RenderAction.

Tuesday, February 09, 2010

Maintainable MVC Series: Inversion of Control Container - StructureMap

This article is part of the Maintainable MVC Series.



To make your code testable the pattern to use is that of Dependency Injection. DI is nothing more than injecting all dependencies of a class instance through the constructor (or setters if you wish, but less intuitive when reading the code, and doesn't guarantee all dependencies are set). For example if you have a controller that uses a factory and a repository you can both inject them into the constructor as follows:



[csharp]
public class Controller
{
private readonly IFactory factory;
private readonly IRepository repository;

public Controller(IFactory factory, IRepository repository)
{
this.factory = factory;
this.repository = repository;
}
}
[/csharp]

Maintainable MVC Series: Introduction

I'm going to do a series on how I've set up a number of ASP.NET MVC projects for customers with very high-traffic sites and continuously changing functional requirements. In these projects the design evolved to the one that I'm going to describe in detail.


The following subjects will be handled in oncoming blogs: