Wednesday, December 29, 2010

ASP.NET Web Forms vs ASP.NET MVC: The Middle Ground

Ok, so it is about time I contribute to this blog as I have been listed as a contributor since it started and have yet to write anything. I apologize in advance for grammatical errors. This is something that has been bothering me for a while and I am seeing more and more argument about this online and among fellow developers and while both sides have their points, I find that there is a nice middle ground that most ignore.

Preface: This is about the .NET MVC framework, not the MVC design pattern. With the exception of one point in the article where I mention the design pattern specifically, any reference to MVC is related to the framework.

ASP.NET Web Forms vs ASP.NET MVC: The Middle Ground

I have heard one problem on both sides "It creates spaghetti code". For MVC it is hard to find where the actual work is being done, where it is posting, etc. For web forms it is the IsPostBack check in the page_load of every page to handle different events and lets not forget the ViewState. Both are valid points in my opinion and I am not a fan of either.

When I started writing websites, I used straight HTML for my pages. My first server side language was Cold Fusion (ugh.) and I never used the built in widgets for rendering. I followed that with ASP 3.0 and that didn't have any (that I knew of). When I started with .NET, I wrote my pages the same way. I never used the web controls provided by .NET, I used normal code. For/While loops instead of repeaters, Response.Write rather than labels, etc. I would use the normal HTML form tags rather than .NET's. I never used .NET's event model, relying instead on javascript and I didn't even know the ViewState existed for the first few years of using .NET.

I would make all of the data I needed for rendering page available to the view after the page_load was complete and that was it. .NET was no longer involved once the page was rendered, and when another page was called I would pull from the Request object for query string or form values and pump data back into the Response object if necessary. If I needed something to persist in the app or session, I used the Application, Session, and Cookie objects provided.

I always felt that this gave a better page lifecycle and user experience anyway, users could use the back button without messing up the flow, and a page only knew how to do one thing, two at the absolute most. I have heard MVC called an advancement of this methodology, and while I agree to a point, I feel it overcomplicates things is some ways.

The first thing that MVC is supposed to provide better than web forms is true separation of concerns. The model does the work, the controller acts a gate keeper, and the view just does the rendering. While all of this is true, I don't see it any better than how web forms CAN be used. Now, I have been told that the way I use web forms is practically the MVC design pattern, so I wonder why is there a need for a completely different set of libraries and handlers if that is the case. What am I really gaining from having the advanced routing methods? Prettier URLs? That is only an advantage for the end user because the views are still hard tied to controllers. Yes, a controller can return something else (such as json) without a view, but that is a marginal improvement at best. The only other advantage I see is less files in the code base, but the controllers are large if they handle a number of actions and can be a bit of a pain to search when you are looking for a specific one. In web forms, I know exactly where to look for my files based solely on the URL. The code behind can (and should) act as a "Controller" with one action. It will talk to the "Model" and handle flow control and redirection based on the request data or the "Model's" response. With the exception of smaller websites that have very little business logic to them, the "Model", whether in in MVC or Web Forms (in a perfect world) is separate from the website anyway. Whether it is a one or two-tier app with business logic in separate libraries/classes, or it is a separate entity (WCF, Windows session, etc) in a n-tier environment, the "Model" is already separate. So once again, MVC is not providing much.

I think the key thing with Web Forms has stirred up so much ire from the development community is the "pluggable widget model" (as D2 calls it). The intent behind the Web Forms design pattern is to act like a WinForm app, and since the early days of VB, WinForm development has been very much plug and play. Developers just drag and drop objects where they want them then wire it up in the back end. In this "controlled" (I use that term lightly) environment, it worked pretty well, but the web world is not as controlled. Programmers don't have the luxury of controlling every action of the user(without some crazy javascript, and that is only if javascript is enabled), only the browser does. After a web request is complete, there is no longer a connection to the server until the client does something else. That is the nature of the web. Embrace it.

When many developers tried to make the shift, from Win to Web, they tried to follow that ideology, not remembering that users, for the most part, are dumb. They don't read your warning not to use the back button, and for the most part, don't care about how you want it to be used, they will use it way they think it should be used, and this causes a lot of headaches. The result was spaghetti code.

The other cause of spaghetti code was the RAD model that Web Forms allowed. People with little to no development experience could create a website that did all kinds of flashy things and provided the end result they wanted without having to worry about silly things like security or maintainability.

In either case, these developers carved out a nice little niche and business types liked their quick turn around and usually low prices so they were hired to write apps that later needed to be maintained by others. Sometimes those others were similar developers that made the code base worse, and other times they were real developers that spent much of their time beating their heads against the wall and sending snippets to The Daily WTF, all while being told by the client that they don't understand why it is so difficult, "It's just a web page".

Like I said earlier, I don't like the Web Forms design model, and I don't see any real reason to use .NET MVC. Both have their advantages and disadvantages, but if you write code with the mindset of how the request/response model works and write your own html, why not use what .NET provides by default? This makes deployment easier as the boxes that house the web app will not need another set of libraries installed on top of .NET, and maintainability is a lot better because of the better codebase structure. This also ensures that your JS and CSS will act the way you expect them to and that you get a lot more control over what is happening at all stages.

7 comments:

  1. Well the point of using a framework is similar to the point of using a higher level language. It hopefully provides you a means to thinking and working at a higher level that is beneficial. If I end up having to do a bunch of IL injection or generation in C# maybe it's time to think about using a dynamic language.

    So certainly you don't need any frameworks to write a web application so long as you have an OS that provides network IO access (you could even debate that), but I doubt you'll really work at that level. Most likely you'll end up duplicating a lot of code for how you work or you'll end up with your own sort of framework. If your framework ends up similar to ASP.NET MVC for example, then perhaps that was a wasted effort.

    Those are my thoughts on frameworks in general, so now for a little on WebForms.

    WebForms is basically a lie. They try to wrap up web development with desktop development. Unfortunately there is a mismatch and you end up getting caught up dealing with the abstraction instead of working with it. What I mean by that is you usually end up having to worry about the page or control lifecycle and worrying about control ids and dynamically creating controls or loading data in the right places. WebForms for me starts to fall a part once you can't just use a ready to go controls on a page that contains a static set of them. For me WebForms is a framework that provides an non-beneficial abstraction, statefull eventing, for web development, action (post, get, delete, put) based message passing.

    Meh, might as well include some thoughts about MVC.

    MVC may have originated from the minds behind Smalltalk trying to separate out their code for GUIs, but it has become a widely recognized successful object-oriented pattern for web applications. Because of that I think frameworks that allow you to work with the pattern easily providing correct abstractions are a must. This doesn't mean that other frameworks or raw HTTP code wouldn't do the trick, but it doesn't mean that you wouldn't benefit.

    ReplyDelete
  2. OK, it just ate my big comment. I'll try to write something later, for not the baby is going crazy.

    ReplyDelete
  3. Agreed, the point I was trying to make is that it isn't necessary to follow a similar pattern. If you throw out all the web forms components of web forms and use straight html, you get everything that the MVC framework gives you minus the routing (which I don't personally enjoy working with anyway). If you look at both as a toolbox, the basic tools of web server-client communication is in both. Response, Request, Cookies, Sessions, and Application, plus the ability to render views using the standard rendering tags (<%= %>) and code blocks (<% %>). That is all you need to make a highly functional and scalable website. MVC frameworks offers some extra tools, and web forms offers some useless tools as well, but if par it down to the basics, there is no reason that you would need the MVC framework, or deal with the web forms life cycle.

    ReplyDelete
  4. BTW, your first comment did make it through

    ReplyDelete
  5. Well son of a bitch. I really thought it ate it from the error I got from submit.

    Low level .NET web you wouldn't get filters, parameter/model binding, controller building, view locating, etc etc. Just saying, the MVC framework does give you a lot that you don't have to write, mature, realize you need but didn't plan for at the cost of learning the framework. Also since it's open source you can still dive into the code and take control.

    I agree that you don't always need something like MVC framework. If you look at the Ruby world, they have Rack which provides just some basics. You can write rack apps that act like a middleware but they take in a request object and are expected to return something that will generate a string for the response. On top of that web frameworks start to build up their functionality. Rails 3 puts routing, controller building, view templating, etc for their MVC framework but you don't have to take it all or nothing. If I remember correct Sinatra builds on top of rack to provide a simple means to tie HTTP action and request url to code. Nothing too fancy just "get '/the/url' do ... code ... end".

    So you really gotta evaluate the technology like always. Any mature MVC framework is probably a safe bet for general web development, but could be way to heavy if you just need some kind of basic REST style app. Which could still be too heavy if you were serving static pages.

    I'm actually going almost the reverse thoughts on writing JavaScript. jQuery seems to be a bit too low level and I'm trying to figure out how I would like to write JavaScript applications.

    ReplyDelete
  6. Oh it's cool to see you writing. I need to try and write some more. I have a couple of post ideas sitting as drafts.

    ReplyDelete
  7. I rather enjoyed it, I plan on writing some more in the near future. Not sure what about yet, though.

    ReplyDelete