Developer's Perception

Odd thoughts from a developer.

Maintainable ASP.NET Webforms - Part I

| Comments

In the next couple of blog posts I will try to outline how I try to improve the maintainability and testability of pages written in the ASP.NET Web Forms framework

Don’t use ASP.NET Web Forms

If you are not forced there is no good reason to use this technology. There are many better ways to write your web applications. If you wish to work with the .NET framework you might consider:

  • ASP.NET MVC latest incarnation (if it just has to be Microsoft)
  • Nancy (nice open source framework)
  • … and other options

If your wish to use something other than .NET there are also many options (the reason I base this decision on whether you want .NET or not is simply because we started out discussing alternatives to Web Forms):

  • RAILS, Sinatra, Goliath and other options on Ruby.
  • Django on Python.
  • Node.js potentially with the express framework.
  • … and lots of other options.

Point is: First way to improve your Web (Forms) code is to not use Web Forms.

I Have no Choice

If you are stuck building Web Forms, it is most likely due to working on a legacy system build with this technology. There are lots of those out there and they are not getting upgraded to better options (at least not all of them).

Thus, we have to manage somehow.

The main tactic I advocate for coping with the platform is a pattern called MVP (Model-View-Presenter): MVP(Go down a bit to find the description)

Now this may not be the most easily accessible description and potentially you might not be able to implement the pattern in your application from this description (or it would require quite some work).

There is a catch to the pattern though. If used correctly it can help make your code more testable and easier to reason about, but it adds complexity and will not save you from having to know about viewstate, page lifecycle and other details about Web Forms.

Bits and Pieces

Not surprisingly we need a class for each of the roles of Model, View, and Presenter (actually a bit more).

Model

The model is just a PONO (plain old .NET object) and can be your domain model or alternatively a view model. When to use a view model is largely a matter of taste, but I prefer not to do it unless I actually use it for something as it does add an overhead of an extra class and mapping code (consider using a tool like automapper if you do have both models).

View

The view in our ASP.NET webform MVP implementation is basically our code behind file and the aspx file can be considered a template for helping with rendering the html. The key is to keep the code behind file very very slim as the view can typically be very hard to test due to dependencies on ASP.NET.

The responsibility of the view is to render html, retrieve values from the html (really being the viewstate), and kicking of the flow (that is the way webforms work).

The view is hidden by an interface to save the Presenter from knowing the gritty details of webforms. This way the presenter could also be used in another application that is not necessarily for the web.

The view initializes the presenter with a reference to the view itself – typically in the pageload event, but that really depends on the purpose of the page.

Presenter

The presenter is somewhat similar to the Controller in the MVC pattern, at least in the way I use it. It is not triggered in the same way as in MVC, though, as the view has to start it up.

Basically, the presenter handles the flow of the page, receiving data from the view when an event occurs (a button is clicked for instance), using lower level constructs (like data-layers or services) to manipulate data and then typically asking the view to render something. I would never have a presenter function return a value, as it is solely up to the presenter to determine what the view should do (not how though).

The presenter will get a reference to the view through the interface in the constructor.

In .NET this leaves us with 5 pieces:

  • A View (for instance SearchDogView) which inherits from System.Web.UI.Page.
  • A template used for rendering html for the view (the ASPX file).
  • An interface for the view (ISearchDogView).
  • A presenter (SearchDogPresenter)
  • A model (or 2 if we decide to use a ViewModel)

Part II: A tiny example

Comments