ASP.NET MVC: From Webforms to MVC - Introduction
This is the introduction for the book I've decided to write. I'm not at all sure how it will see paper yet, and I'm OK with that. I've been looking into self-publishing or on-demand publishing and I'm fairly convinced that it's a real option. I'm still willing to talk to "real" publishers as well, and as usual, I can be reached at jeff at popw dot com.
This is a very rough draft with very little copy editing or polish. I'm looking for feedback, though I understand there isn't a lot to give for an introduction. It does, hopefully, reveal the approach I'm going for. There will be more to come in the following weeks...
The text is (c)2009, Jeff Putz, all rights reserved.
EDIT, See also:
Chapter 1 - The M, The V, The C and Plumbing
Introduction
Here we are, a new day, a new framework. The buzz on the Intertubes is loud with tales of ASP.NET MVC, a framework that adopts the model-view-controller pattern and applies it to Microsoft's Web application platform. It was built and developed almost completely in the open from late 2007 up until its final release at the Mix09 conference in Las Vegas.
I was there, in fact, and attended the sessions. I watched Microsoftie Scott Hanselman entertain and inform the crowd by doing a demo without any slides, just code. There was much rejoicing among the attendees. And maybe some groaning too, about learning something new.
What is MVC, and why bother?
MVC stands for model-view-controller, a design pattern. If you believe Wikipedia (and who doesn't?), it was originally conceived in a paper about Smalltalk way back in 1979. The fundamental belief of this design pattern is that, in an object oriented sense, you can enforce a "separation of concerns" between the three components. This loose coupling allows you to swap out the pieces with less grief while increasing the ability to test your code. That's exactly how Scott Guthrie of Microsoft introduced it in November of 2007.
--sidebar
It’s actually fun to see how the framework evolved, and Guthrie’s blog serves as a great history of this evolution. Here’s where it began:
http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx
--/sidebar
The three "concerns" or components are:
- Models: These are the components of your application that do the heavy lifting. You probably already have these in your Webforms projects, or any other kind of object-oriented development you do. They encapsulate logic, data access, rules and other entities. When done right, they should be able to execute in isolation, with no dependencies on a user interface. For example, if you have a class that logs some kind of security action by users, it shouldn't know or care about a Web site or its HttpContext. It would only need to know that some other entity will give it things like user names and IP addresses.
- Views: The user interface is a view, or the way that humans see and enter data. Just as models don't care about the Web, a view doesn't care one way or another about how your application logic will eat and process your credit card number or middle initial. It doesn't care where the "credit card declined" message came from either. It's like a slacker or atheist or something, never looking for deeper meaning.
- Controllers: These things are the ringleaders, the glue, the middlemen (or middlewomen) between the views and the models. They don't calculate tax or send e-mail or figure out how many forum posts you make per day. They choose what you should be seeing, and where to hand off the data that you've entered. They're kind of like project managers in that respect, in that they don't do anything other than coordinate the expectations between workers and managers.
This is typically the point at which you'd see a diagram of the three entities in action, but we'll save a tree (and/or bits) and let you draw it yourself in the margin. It's not hard to visualize.
I may be editorializing, but it could be argued that MVC has done a great deal to simplify and focus the development of Web applications. The pattern tends to get us thinking about specific tasks at hand, and a side effect of that is that it reduces the complexity of the user experience. When we see a URL with a path like "/chocolate/create," it's pretty easy to figure out what we as developers should be doing at that point.
One of the big success stories of MVC as it pertains to the Web comes from Ruby on Rails, a framework released as open source back in 2004 by one of the founding partners of 37signals, a relatively small but successful company that builds Web-based applications. It was the first time I had heard of MVC (a computer scientist I am not), and I thought it was a very interesting way to quickly build stuff without all of the customary and boring stuff I had to do every day in ASP.NET. It wasn't quite compelling enough for me to jump in and learn Ruby. Still, it did capture my attention.
--sideabar
People seem to have a love-them-or-hate-them feeling for 37signals, their “Signal v. Noise” blog and their e-book, Getting Real. I don’t agree with them all of the time, but I can’t ignore the fact that they tend to challenge a lot that we “know” about how business is supposed to be, especially in software development. I dig that.
--/sidebar
Rails got a lot of traction not only with the 37signals products, but also sites like Twitter. One of the most impressive examples I've seen is Ravelry.com, a community site for knitters and those who love yarn. My wife visits every day. One developer builds and maintains that site while his wife manages the community. They have a Boston Terrier too, though I'm not sure what his role is.
Why should you, the ASP.NET developer care that there's an MVC framework for your beloved platform? Because it may open some doors that make developing applications faster and require less work, especially when it comes to using AJAX and more client-side goodies.
Good old ASP.NET proper comes with a lot of baggage. It was built to a large extent to simulate the statefulness of a traditional desktop application, making it easy to pick up for armies of VB6 programmers circa 2002. It comes with events and mechanisms that behind the scenes "remind" the server how the form looked before you did something to it, then it does some work and sends back the updated state of the page. It's a somewhat heavy process that produces a lot of markup in the HTML that you may not entirely need or want. It's powerful, but it might do a lot more than you need.
The biggest win, in my experience, is the ease with which you can manipulate the DOM on a page and perform AJAX calls, thanks largely to jQuery, a popular and powerful open source Javascript library. You can do this today with Webforms, certainly, and the ASP.NET AJAX script library allows you to do it in a way that encapsulates the server and client code in a somewhat awkward harmony. But given the often weird markup that ASP.NET generates, it's not very straight forward.
--sidebar
It should be noted that ASP.NET 4.0 will do a great deal to help you out here, by giving you better control over Viewstate and the client ID’s rendered in the HTML. Yes, that means you won’t have to figure out how you’re going to change the background color of ctrl00_ContentPlaceholder1_AddressBox_Message!
--/sidebar
Does this mean that you should toss ASP.NET Webforms out? Absolutely not. Like anything, some tools work better for certain things.
The pros and cons
ASP.NET MVC has a lot going for it. If you're a control freak, you'll love that the HTML it produces is clean and exactly what you want. If you've used Webforms for any length of time, you know that sometimes the CSS you apply to something a WebControl generated yields completely strange or unintended results. Since the basic HTML helper methods generate simple markup, if you use them at all (they certainly save time), the end product is more of what you expect. Oh, and there's no Viewstate and scripts you can't explain.
The ability to truly serve up different views based on device is remarkable. In the Webforms world, you'd need to rewrite the logic in your page's code-behind to bind the right data to the right controls, and likely do it differently for the mobile pages. In fact, you may have a totally different site for the mobile version, which is a lot of extra work.
Because of the strict separation of concerns, you can test more code than ever. What we call the models here, your data entities and application logic, should be testable even in your current world. Now add in the controllers, which accept data and then pipe data back out. There has never been an easy and elegant way to test this logic in Webforms because of the overhead around the instantiation of a page object and its dependencies on HttpContext and its various properties like Request and Response.
The URL routing system is particularly friendly for search engine optimization. Granted, this is a moving target for those who make a living trying to figure out how Google works, but even the common human can see a URL like "/news/cake" and instantly recognize it. The user that sees "/news.aspx?type=cake" may not. And hey, every win for link juice on Google can lead to more money in your pocket. Unless you're Twitter.
Visual Studio's MVC tools have a lot of goodness baked right in. It will generate a strongly typed view based on one of your entities, and depending on your method of storing data, it may only require a few lines of code to save user input. So with a right-click and a few options, you're rocking out with a form that can display data, and create or update it. When used with LINQ to SQL or the Entity Framework, you're in business quickly.
It's not all rainbows and puppies, of course, when it comes to ASP.NET MVC. First and foremost, it's a newer framework that fewer developers have worked with. Scarcity forces higher salaries. There's less experience out there because it simply hasn't been around as long as Webforms.
It also lacks the kind of UX encapsulation that we get with Webforms. For example, I have a template based image gallery control that I've used time and time again. The markup that appears in each cell of the table can be anything I want, and I can tell it to leave a "hole" for a template containing an advertisement. All I do is drop it on a Webform and fill in the templates and it automagically works. This kind of reuse isn't in the strictest sense possible in MVC if you're adhering to the design pattern.
The magic of having a simulated stateful form is also gone, with no postback mechanism. The entire event model is thrown out.
Views feel a little like spaghetti code from old ASP (the scripting platform that used the tragic VBscript). Perhaps this one isn't entirely fair, because if you're really separating concerns into the model-view-controller pattern, what code you do have in the view should be little more than looping through a data collection or hiding something based on the data's value.
And the biggest concern I have is that developers won't be thinking about security the way they should. It's already possible in Webforms (or any other platform) to put together an HTTP request with the right information to simulate a legitimate user action and do naughty things when the right preventative code is not in place, but it's even easier in MVC. A URL like "/cats/kill/42" is probably intended to execute cat.Lives-- and it's easy to guess. A lot more care has to be taken to validate data and enforce security.
Stuff you need
So now that you're convinced you want to use ASP.NET MVC, what do you need? The fine folks at Microsoft outline the details at http://asp.net/mvc, but here's a quick recap:
- .NET Framework v3.5 with Service Pack 1
- ASP.NET MVC v1.0 (this you'll have to download)
- Visual Web Developer 2008 Express with SP 1 (another free download) or Visual Studio 2008 with SP 1 (not a free download).
Other tools that make your life easier:
- Firebug, the Firefox plugin that gives you an inside peak to the goings on of the DOM and Javascript.
- ReSharper plugin for Visual Studio by JetBrains. Seriously, in a world where you iterate and refactor every day, you need this.
The sample app: CliqueSite.Blog
Another blogging app? You bet. I chose to build a blogging app because it's a fairly simple thing to get your head around, and it includes the most common use cases for building Web applications.
The application will likely evolve beyond the static version of this book, but we'll always keep the version that matches the book available for download. You can get it here:
http://xxxxxxxxxxxx/
Who is this book for?
This book makes some assumptions about what you already know. I will not subject you to all of the introductory concepts of ASP.NET, object oriented programming, HTML, CSS or Javascript. This book is for developers who have experience using Webforms and Microsoft's platform overall.
Read on if you hope to learn the following:
- Learn the approximate analogs between Webforms and MVC, categorized by common use cases you already know.
- What the model-view-controller pattern is, and how it's used in the ASP.NET MVC framework.
- How to use an object relational mapping framework (ORM) in an ASP.NET MVC application. We'll be using LINQ to SQL.
- Achieve better test coverage throughout your application.
- Use AJAX and DOM manipulation to make a slicker, less chatty app.
- Get down to the basics of sending bits to the browser.
The book also assumes that you understand C#. This is not an indictment of VB.NET or anything, but rather a nod toward the larger audience. Even if you do use VB.NET, the syntax of C# should be easy enough to understand.
Suggested approach to reading
This book starts out with the bigger concepts used in ASP.NET MVC, then goes on to the specific use cases that you'll need to get things done. You may want to simply read cover to cover, but after the first chapter, feel free to skip around to satisfy your curiosity. You may have little use today for creating your own HTML helpers, but chances are that getting data in and out of a form is a top priority.
For help and errata
Visit http://xxxxxxxx/ for the latest information on this book. If you'd like to contact me, the author, drop a line to xxxxxxx.