Sunday, January 9, 2011

The Right Tool For The Job

I just finished reading Davy Brion's latest blog post, entitled "Learning To Work With The Web, Instead Of Against It."  It's one thing to say that I agree with his point, which I wholeheartedly do, but it's another entirely to continue the point and take it in hopefully a relevant, albeit tangential, direction.

Lately I've been on something of a crusade on "using the right tool for the job."  It's becoming sort of my mantra for software craftsmanship.  The idea is that the tool is less important than the craftsman.  It's more important for a developer to perform a job well and produce a well-crafted product than it is for a developer to produce a product that fits within some contrived notion of what that developer should be doing.  I often sum up this idea by saying, "It's better to be a developer who knows .NET than to be a .NET developer."

Now as you may already know, I am a web developer by trade.  I specifically develop enterprise web applications on the .NET platform.  I've been doing it for a while now, and I like to think I'm pretty good at it.  You may also know that I look back on web forms with a kind of shame.  Sean, you know what I'm talking about.  It got the job done, sure.  But was it the right tool for the job?  Was it the right approach?

Davy touched on this a good bit in his post.  The age of web forms is by no means over (at least not in the more stuffy and slow-to-progress corporate environments).  But the ASP .NET community has poked its head above the water enough now to at least look around and see what else has been going on, and to get a more high-level view of web forms and what it really was.  It was the wrong abstraction.  (It looked like a duck, quacked like a duck, but needed batteries.)

Web forms represented a fight against the "web way of doing things" and an attempt to push that under enough code (using the dreaded "pluggable widget model," my arch nemesis in software craftsmanship) that developers wouldn't need to worry about all that web stuff and could just focus on good old rapid application development.  And, as Davy pointed out, what did this lead to?  Too many post-backs, slow load times, poor web software in general.  It was a web platform that actively fought against the nature of the web, attempting to obscure and deny the very foundation of what it was doing.

Now, in the past year I've held four different jobs.  Career-wise, it's been an interesting ride.  But it's given me an opportunity to work with a lot of different people in various corporate cultures and learn a lot about how corporate developers can think and work.  And I hate to say it, but a lot of times the focus is incorrectly placed on the tool rather than on the craftsman.  And the tool in question at the moment is ASP .NET.

There's an old saying, "Nobody ever got fired for buying Microsoft."  And since Microsoft is in the business of building and selling tools, this kind of mentality has led to too much focus on the tools and not enough on the craftsmen.  No, I don't have any Microsoft certifications.  No, I'm not a Microsoft MVP.  I'm not interested in those things.  I see no value in them.  (If you do see value in them, then by all means go ahead and use them.  Value is relative, it's all in the perception.  So don't think that I'm somehow de-valuing your own expertise for the sake of my own, because I'm not.)

The point that I'm getting at is that I've seen a good number of developers who cling to ASP .NET as a kind of catch-all tool that can be used to address all of the requirements they face.  And, even worse, they maintain a very narrow view of what ASP .NET can do for them.  If it's in an MSDN tutorial somewhere, or on a ScottGu blog post somewhere, then it must be right because it's the Microsoft way of doing things.  It's safe.  It's the tool we use, and we must obey the tool.

Unfortunately, this has led to a whole industry of "web developers" who know little if anything about HTML, CSS and JavaScript.  These are the core components of web development today.  Everything you present to the user in ASP .NET gets translated into these technologies.  But the tool does everything it can to hide that fact from the developers, and thus the developers remain blissfully unaware of it.

In my travels this past year (not just at work, but also in helping people on Stack Overflow), I've heard such interesting (and frightening) statements made by web developers as (paraphrased):

  • "I don't know JavaScript, so I can't support that.  Write it in .NET instead."
  • "Why should I use CSS?  I can just set the properties on the controls."
  • "What do you mean there are too many post-backs?  How else is it going to use the code?"  ("The code" in this case was simple string manipulation in the UI, nothing more.)
  • "Why didn't you convert this HTML to .NET?  Isn't the site written in .NET?"
  • "We can't use Rake, everything we do has to be done from within Visual Studio."
  • etc.
On another note, I've also heard my fair share of non-developers, the business users in an organization (managers, sales and marketing, executives, etc.) make some interesting comments.  And my favorite one for this discussion is simply, "If these other companies, like Google, can make such great web applications, why can't we?"  (Well, first of all, Google pays for top developers and treats them with respect and admiration.  Google's bread and butter is web development, so as a business it does everything it can to foster the capabilities of its developers.  Many of you, on the other hand, see your developers as servants who must be kept in their place.  But I digress.)

Well, just take a look at Google's products and how they're crafted.  They don't do anything "the Microsoft way" or "the Sun way" or "the Oracle way" or any other way.  They do things "the Google way" and, by that, they do everything they can to use the right tool for the job and use it well.  Rather than pick a tool and try to fit all of their requirements into the skill set of that tool, they use whatever tools are at their disposal.  They even make their own, if the need arises.  In developing on the web as a platform, they have demonstrated beautifully the importance of this.  They have embraced the tools of the web.

Look at Google Maps as an example.  Let's say your company wanted to build something like that.  Could you build it in ASP .NET with Microsoft's pluggable widgets?  (Well, you'd use some Bing stuff instead of some Google stuff, but you get the idea.)  Sure.  Would it be as sleek and polished and well-received as Google Maps?  Not a chance.  Your ASP .NET map site, though it uses the approved and well-established tool(s) you love, wouldn't be using web technologies properly in this particular case.  All the functionality may be there, but the user experience would be kludgy at best.

Google employs a lot of JavaScript in a product like that.  Plain old JavaScript.  That same language you used twelve years ago to make text-box-based tic-tac-toe games in your browser, or to make little swinging tails that follow the cursor, or to make a scrolling marquee in the browser's status bar.  But they didn't just use it, they embraced it.  They didn't just write code that happened to be in JavaScript, they embraced a fundamental understanding of what web development is and how it works and where JavaScript fits into that.

For every ASP .NET developer I've seen avoid JavaScript, I've also seen one who "uses" it, by which I mean they copy/paste somebody else's JavaScript code onto their page in order to accomplish something.  You know what that is?  It's a pluggable widget.  It's a block of code that the developer didn't write, and more importantly doesn't understand, but somebody said it'll work and it seems to get the job done so they go ahead and use it.  (I'll admit it, I've done this many times in the past.  But no more.)  Sure, it's JavaScript, but it's not the tool that matters.  It's how you're using it.  You're using that JavaScript like any other ASP .NET web forms control.  You drag it onto the page and forget about it.  You don't know (or even care) how it actually works and what it actually does.  In other words, you're still denying the very nature of web development while you are engaged in web development.

How do you think Google's products would work if they did that same thing?  It would be a mess.  So, to answer those business users who want to know why their development teams can't do this, it's because their development aren't embracing web development properly.  They're trying to fit the web into their toolbox, rather than expanding their toolbox to embrace the web.  You can't change how the web works.  Honestly.  New things come along, sure.  But you're still talking about HTML, CSS and JavaScript on the client side and some back-end technology on the server.  You're still talking about a stateless request/response model.  There are abstractions to this, some more successful or useful than others, but you have to embrace the fundamentals of the platform itself.  You can't abstract yourself away from the very foundation of what it is you're doing.

Davy's last paragraph was short and simple, and just a touch of inspirational:
I don’t know what you will do, but i know what i’m going to do. I’m going to learn how to work with the web instead of against it. I’m finally going learn HTML. I’m going to learn CSS. I’m going to learn JavaScript. I’m going to learn about REST. And i’m going to be using that knowledge years from now as i follow the further evolution of the web.
I wish more developers would espouse that kind of attitude.  Replace "I don't know JavaScript so I can't support that" with "I should learn JavaScript so I can better support, or even better create, web applications."  I'm still learning too, Davy.  My HTML is pretty strong, my JavaScript is getting better all the time, my CSS is limited by my poor graphical layout and design skills.  (I'm one of those people who just tinkers with the CSS unit it works, rather than actually writes it from the start with a real plan and a real understanding of the tool.  At least for now.)

The web as a platform (I still don't like that term for some reason.  I need to figure out why.) is rich, engaging and strong.  And web development is, at least for me, interesting and fun.  So stop hiding behind your tools.  Stop clinging to the software development model that Microsoft has tried to force upon you.  Keep in mind the market forces behind a lot of Microsoft's decisions.  When ASP .NET first came out, Microsoft was pitiful for web development.  They designed it in part to allow VB6 and COM developers to be able to jump on the web bandwagon.  Don't get me wrong, ASP .NET has come a long way and I love a lot of what the community has produced.  But the old cruft is still there.  Scrape off that cruft, and embrace web development.

P.S.  I would like to point out that some of the people I've worked with in the past year are not the ones I'm talking about/to in this post.  For the most part, you all know who you are.  Some of you have in fact been a point of much inspiration for my work.  Sean and John are the most relevant examples of this.

Friday, January 7, 2011

On PDFs

Microsoft is ubiquitous.  PDFs are ubiquitous.  So why the hell don't the two get along?

For those of you keeping score... It's 2011, I'm running the latest and greatest Windows, and I still need to hunt around for some damn third party tool just to print to a PDF file.  I don't care if MS Office can write to a PDF.  I don't open everything in MS Office.  (If I had my way, I wouldn't open anything in MS Office.)  It should be integrated with the print system.  You have no excuses.

Yes, I know I can print to an XPS file.  I can even print to a TIFF using the "Microsoft Office Document Image Writer" (sounds fancy, doesn't it?).  But nobody, nobody wants to do either of those things.

Tuesday, January 4, 2011

Quick and Easy Facebook Integration

I figured I'd take a break from the soapbox-style posts I often write and take a step back to another of the original ideas regarding this blog... Sharing something quick and easy and potentially cool to do in code.  This one comes inspired by a handful of Stack Overflow questions I've answered on the subject, and may indeed serve as a simple place to point users to if they ask more similar questions in the future (unless, of course, it's an actual duplicate question and can just be referred to the previous question, as is the SO way).

Facebook development and integration is nothing new.  Come on, man, everybody's doing it.  Don't you want to be cool?  Indeed, while I'm sure that a lot of people/companies are doing this, and while it's evident that a lot of them meet with a great deal of success in the matter, my experience as of late seems to indicate that many people/companies toy with the idea but have no clue as to how to actually implement it.  Well, product folks can undoubtedly come up with all the marketable and sellable ideas they want in this matter, but success or failure may hinge on the simple idea of know how the Facebook platform actually works.  It's one thing to say "we need more Facebook on our site!" and it's another thing entirely to come up with an actual workable solution.

To that end, let's take a look at some very basic Facebook integration.  You may or may not have heard of their Graph API, which is basically a JSON service for getting information our of their "social graph" (the various data objects they track and the relationships between them).  Getting that data, once you have permission that is, is actually very simple.

First, you need to create your application on Facebook.  (This step is a lot easier than it sounds.)  Basically, give Facebook some simple information about your website and how it'll be integrating.  Start out with something simple:
Facebook has some restrictions on the format of the Site URL, I usually just give it a folder where I'll be putting my Facebook-ish stuff on the site.  The page you ultimately want to reach in this process is this one:
Congratulations, you now have a "Facebook app."  Now what are you going to do with it?  Well, keep in mind again that the approach I'm taking here is for interfacing with the Facebook Graph API from your website.  You know, visitors come to your site, they use their Facebook account (since they're most likely logged into Facebook in another tab) to "Like" your site, you harvest their data and spam their friends, etc.

So now you need to add some Facebook stuff to your site.  Note the sample code in the preceding screen shot above.  This code does a couple things:
  1. Initialize your page with your Facebook app.
  2. Present the user with a Facebook login button.
  3. Present the user with a Facebook "like" button.
Let's take a look at the JavaScript first.  It's doing two things.  First, at the bottom, it's writing to the DOM a script tag to load the Facebook JavaScript code.  Second, above that, it's binding an initialization function to a Facebook window load event.  You supply it your application ID, pass other arguments per its documentation, and your page is now ready to interact with Facebook (or, rather, allow the client-side user to interact with Facebook).

Next, the login button.  This is using FBML, which will be handled by their JavaScript code and translated into what it needs to be on the page.  You can create mildly a customized login with a few given parameter, but the basic thing you need to do here is ask the user for permission to access their Facebook data.  Take a look at the "Login" section of this page (recently updated).  The simplest approach, which is what we're doing here, is to ask the user for some permission to their data.  This is done by decorating the FBML login tag with some permission request modifiers.

This is where the user grants or denies your site access to their Facebook data.  If they deny you, then your work ends here.  But if they allow you to access the data, then this is where you'll be able to send requests to Facebook on their behalf.  You can go so far as to, if permitted, post stuff to their wall or send messages to their friends, etc.  But, again, we're sticking with the basics here.  We want to see the Graph API data.

Once permission is granted, Facebook writes a cookie to the user's computer which you can use.  Remember that "application secret" value from before?  You use that to decrypt the cookie.  Take a look at this PHP code (which can still be found here, though they change their documentation a lot):
Notice how it's using the application secret string to decrypt the user's cookie, and from that cookie pull a critical piece of information... the access token.

(Note: You must never share your application secret with anybody.  Don't render it to the page, don't use it anywhere but your protected server-side code.  Anybody who has this value can pretend to be your application and can spoof users and Facebook as you.  The access token you pull form a user's cookie should also be treated with this level of secrecy, with one exception.  You can render that to the page, since you're pulling it from the user's cookie and just showing it back to the user.  However, proper use of SSL is, as always, recommended.)

Note how the PHP code then makes a simple Graph API request to get the user's name.  In this case, the "me" in the Graph API URL is being interpreted by Facebook as the user who owns the access token.  There are a number of ways to access a particular user's node on the graph, this is just one of the shortcuts.  But basically, this is what you're looking for.

These Graph API requests are just URLs with query string parameters, and they just return JSON.  (The data structure is generally fields of data with the occasional object field which has its own ID and can be requested as its own node on the graph.)  So the requests can just as easily be made from your JavaScript code on the client-side or your server-side code.  Each has their advantages and disadvantages (I prefer to do as much in the JavaScript code as possible in this case):
  • Client-Side: You offload some of the work to the client's machine.  The performance implications here are obvious, but for me the main one is that the client's browser is probably better suited for multiple parallel requests than your server code.  Let it handle it.  Otherwise, you risk have your client sitting and waiting, even if just for a moment or two, while you make requests on their behalf.  Just do it in JavaScript and let their browser handle it.  Also, one big thing to note here is that you can tell your users that their data never actually touches your server.  It's all from Facebook, you never see it.  People like privacy policies that can make claims like that.
  • Server-Side: Once you have that access token, you can continue to make requests for data on their behalf.  So in an offline process you can start harvesting.  (Yes, it pains me to say that.  Let me explain...)  You can, say, loop through their friends list and grab email addresses (assuming their friends allow that, they have privacy settings too) to compare with your local data store.  Then you can prompt the user with such gems as "I see your friends are already members of this site, would you like to say hello?" or "Your friends haven't signed up for this site, click here to invite them."  And so on.  Act responsibly, of course.  The user trusts you with their data, don't betray that.
That's about it.  As I'm sure you saw in some of the links, there's a lot more that can be done.  A new addition to the documentation (new as in added this week, I hadn't seen it until I started writing this) is the registration stuff related to the Facebook login button.  It sounds like it can be used to facilitate users registering on your site by pre-populating fields with data they already have on Facebook.  (Of course, I recommend looking into OpenID and OAuth for stuff like that, as Facebook supports both.)  There's also quick little social plugins and other widgets you can add to your site.

Keep in mind that the Facebook documentation changes all the time.  They're known to have broken internal links, pages which link to themselves, etc.  But there is a lot there.  Once you're started with something as simple as the above example, the learning curve flattens considerably and you can branch out a lot through their FBML, JavaScript, and Graph integration options.

Thursday, December 30, 2010

F* Yeah! 2 + 1 * 3 = 5

I spent some time lately just reading about compilers a little bit. Nothing too in depth but I wanted to explore the idea of a basic compiler. So I worked my way through some Wikipedia link jumping. Reading about lexical analysis, parsers, grammars. abstract syntax trees, stack machines, register machines, some of everything. I'm surprised I didn't end up on Kevin Bacon's page.

The Idea

Anyway, after all of that I realized something about an exercise we did in school. Take an arithmetic expression, something like 2 + (3 - 1), parse it into a tree data structure, then evaluate the tree. This was basically a simple compiler. We didn't have to describe the lexical and grammar rules, nor generate an intermediate or executable representation, but it was still the same idea. Given this, turn it into something else.

So that sounds like a perfect project, so lets do it in Erlang.

The Lexer


I know the tokens I want: +, -, *, /, number, (, )

After a bit of research I find that Erlang has a lex implementation call...wait for it... leex. Given some lexical rules (defined with a bit of regular expressions and Erlang code) it'll generate me the Erlang code for the lexical analyzer.

Well that's easy. Here's are rules to turn a string representation of an expression into a series of tokens:

[0-9]+ :
  {token, {number, TokenLine, list_to_integer(TokenChars)}}.

[0-9]+\.[0-9]+ :
  {token, {number, TokenLine, list_to_float(TokenChars)}}.

\+ : {token, {'+', TokenLine}}.
\- : {token, {'-', TokenLine}}.
/ : {token, {'/', TokenLine}}.
\* : {token, {'*', TokenLine}}.
\( : {token, {'(', TokenLine}}.
\) : {token, {')', TokenLine}}.

[\000-\s] : skip_token.
[\n] : {end_token, {'$end', TokenLine}}.



The Parser


Ok, I have my lexer. I can turn "2 + 1 * 3" into [{number, 1, 2}, {'+', 1}, {number, 1, 1}, ...
That first 1 on all the tokens is the line number. In my current situation I'm only worrying about a single line expression.

Working directly with that list of tokens would be about as fun as fighting a cool monkey. I want to be friends and he wants to look like a badass while throwing poo. This is where a grammar definition and a parser comes in.

And guess what... in the butt? No, Erlang has a yacc implementation called... wait for it.... yecc. So here's my grammar:

Nonterminals expression.
Terminals number '+' '-' '/' '*' '(' ')'.

Rootsymbol expression.
Endsymbol '$end'.

Left 300 '+'.
Left 300 '-'.
Left 400 '*'.
Left 400 '/'.


expression -> expression '+' expression : [ '$2', '$1', '$3' ].
expression -> expression '-' expression : [ '$2', '$1', '$3' ].
expression -> expression '/' expression : [ '$2', '$1', '$3' ].
expression -> expression '*' expression : [ '$2', '$1', '$3' ].
expression -> '(' expression ')' : '$2'.
expression -> number : '$1'.



Basically I'm saying that every list of tokens should result in an expression (a nonterminal). Which could be a number, an expression inside parentheses, or two expressions joined with one of my supported operators. Those "Left " is the associativity, precedence, and token to aid the parser in getting things correctly.


The Generator


I have a lexer and a parser, sweet. What does that mean? I can turn "2 + 1 * 3" into

     [{'+',1},
          {number,1,2},
          [{'*',1},
              {number,1,1},
              {number,1,3}]]}



I know that is a terrible representation, but's an abstract syntax tree represented as a list (brackets) and tuples (curly braces). The '+' token is the head with only a number to its "left" and a subtree to its "right". Since the tokens come out as a list of tuples, we need another method to represent the tree. Lists will do just as well. This probably looks strange to an OOP guy, but structured data is structured data when you are processing and translating.

Well I'm not done. I have an abstract syntax tree, but how do I use it. Lets turn it into a made up stack based machine language:

-module(generator).
-export([generate/1]).

generate([Root, Left, Right]) ->
  LeftExp = generate(Left),
  RightExp = generate(Right),
  RootExp = generate(Root),
  LeftExp ++ RightExp ++ RootExp;
     
generate({number, _Line, Value}) ->
  [{push, Value}];
    
generate({'+', _Line}) ->
  [{add}];

generate({'-', _Line}) ->
  [{subtract}];

generate({'*', _Line}) ->
  [{multiply}];

generate({'/', _Line}) ->
  [{divide}].

That's the whole generator. The top generator() function just visits each node of the tree while the others rely on Erlang's pattern matching to turn a token into an instruction ({number..} into {push}). You are probably thinking why didn't the lexer generate these instructions as the tokens? Well you don't want to combine these truly separate concerns do you? Also the straight list of tokens as they come out from the lexer wouldn't work with a stack machine where you need to push the data on a stack and pop it off to operator on it. Oh, my operator instructions do the popping.... anyway.


The Virtual Machine


Now I'm turning "2 + 1 * 3" into [{push, 2},{push,1},{push,3},{multiply},{add}]. I can go from a line of "code" to a list of machine instructions. Hot damn, but I still don't have the evaluated value.

At this point you might need to know how to read Erlang code, so I'll skip the gist embedding and provide a link to my git repository for the curious:

https://github.com/copenhas/mathexp

Ok, holy crap. What else do we have to do just to evaluate some math? You start the virtual machine (which runs in it's own process), you send the VM your program (list of instructions), then asynchronously it runs the program and finally will send you the return value in a message.

I'm afraid I'll also leave understanding the basics of a stack machine to the reader as well, but the example of a program above should give you a good idea. I don't think I'm strictly following it (I believe they are usually a 0 operand instruction set not a 0-1), but it works pretty well and the code is pretty straight forward.

Nothing impressive, but the title expresses my feeling when I saw it work.

The Absurdity

Here is the absurdity as a series of Erlang code to get that magical (high) 5.... he he he.

{ok, Tokens, _EndLine} = lexical:string("2 + 1 * 3").
{ok, Ast} = grammar:parse(Tokens).
Program = generator:generate(Ast).
vm:start().
vm:load(Program).
vm:stop().
receive {return, Value} => Value end.

Erlang's assignment does data unpackaging (pulls the data out and sets the variable) and pattern matching (the right side has to match the format of the left). That last line would actually print out the value in the Erlang interpreter. This last bit might have been confusing but I'm going to leave you hanging.

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.