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.