MVC in WebForms: The impossible fight to get rid of the views centric world

time to read 6 min | 1015 words

Let me start out by saying that I know of a lot of people that are doing MVC with WebForms, I am doing it myself right now, which put me in the position to talk about the pain that it brings.  Let us consider the traditional MVC pattern:

Now, in such a pattern, who is supposed to be in control? To drive the application? If you have guessed that the "Controller" is the one that is supposed to be in control, you got the jackpot, but missed the boat (am I mixing methapors here?) as far as WebForms-based MVC platforms are concerned.

The WebForm model, a PageController with complex life cycle, has a direct affect on the structure of the rest of the application. After trying to get true MVC working on WebForms, I now believe it to be impossible to get it to work in a way that would satisfy me. My view on views is that they are:

  • Stupid
  • Presentation logic only
  • Do not affect the rest of the application

For the purpose of this dicussion, I am going to ignore the differences between MVC, MVP, Passive View, etc. I don't have an issue with the view doing data binding, UI logic, etc. The problem is that there are only three models that can be used with WebForms & MVC:

  • Front Controller that later invokes the Page - Basically, the way that MonoRail integrates the WebForm view engine. The problem with that is that ASPX isn't really that smart about stuff, so you end up having to do a lot of stuff in the code behind, which means that you usually need to call the controller for stuff.
    This gives you wierd state issues, where the controller method has run, but then it is called again to get more information that the view is needed.
    The main issue is with this are stuff like pressing a button, which is very hard to do in a web-nice way with WebForms, neccesiating to catch the event in the view and then call to the controller again. Ugly.
    This is probably the best approach, but unless you are doing it with MonoRail, it is also the most expensive one in terms of time and investment. JB has some thoughts about this subject, from using MonoRail & WebForms.
    Even when you are using MonoRail, this is awkward.
  • The Page is calling the Controller's methods. This is what I am using currently, but I find that this introduce the same state based issues that I am trying to avoid (orderring of method calls, etc) and it still gives too much responsability to the view.
    It basically make the view a semi controller, because it is what drives the controller. The most painful parts are stuf like GetPolicies(), GetUsers(), etc, which are called directly on the controller by the view to get the data it needs.
    I could do it the other way around, FillData(IView), I suppose, but that gives me awkward model for the state changes that is required in most complex screens. Basically, the FillData() would need to get the purpose for this, so I would have FillDataForDefaultCustomer, FillDataForChangedCustomer, etc.
    Another issue is that my controllers are inherintly multi-views capable. That is mostly because of the architecture of WebForms & Atlas, this requires me to put some of the stuff that should respond to an Ajax call in a web service or HttpHandler. Those are all going to the same controller (same use case), but there have very different needs.
  • Registering to the view events in the controller. This seems to be a fairly favoraite pattern for MVP in ASP.Net. I have issues with that because we now has strong ties from the view's behavior to the controller behavior. I think that methods like: "void OnLoad(object sender, EventArgs e)" are code smell, and they don't give me much separation from the view. In fact, they are Code Behind done right, without dealing with the UI at all.

To be clear, all three methods give me a few things very important that it is very hard to get from naked WebForms, namely: Separation of Concerns & Testability.

The most problamatic part in this is that it is very hard to get view-ignorance capabilities using the WebForm approach, it is much harder than it should, and the page lifecycle issue is paramount in both view and controller.

My current approach in WebForms MVC is the second approach, but it is very easy to add additonal concerns to the view without noticing, and my controllers looks more like a service class than a true controller.

As you can guess from the title, I don't think that this is somethig that can be solved when using the WebForms framework. The view is so centric to the very idea of WebForms that it is impossible to work without its influence.

I am probably going to do another screen cast on this, but at this point I am giving up. I am fed up with approximations. If you want to do MVC in ASP.Net, you wouldn't be able to get the real thing with WebForms.