You are previewing Professional ASP.NET MVC 2.
O'Reilly logo
Professional ASP.NET MVC 2

Book Description

Top-selling MVC book from a top team at Microsoft—now fully updated!

ASP.NET MVC 2.0 is now available and shipping with Visual Studio 2010 and .NET 4. A new update to Microsoft's Model-View-Controller technologies, MVC 2 enables developers to build dynamic, data-driven Web sites. Professional ASP.NET MVC 2 shows you step-by-step how to use MVC 2. You'll learn both the theory behind MVC 2, as well as walk through practical tutorials, where you'll create a real-world application. Topics include transitioning from ASP.NET development, as well as an overview of related tools and technologies, including LINQ, jQuery, and REST.

This book is divided into two very broad sections, each comprising several chapters.

The first half of the book is concerned with introducing the MVC pattern and how ASP.NET MVC 2 implements that pattern.

Chapter 1 "NerdDinner" uses a small but complete application to walk you through how to build an ASP.NET MVC 2 application and some of the core concepts behind ASP.NET 2 MVC.

Chapter 2 "Model-View-Controller and ASP.NET" starts off with a description of the Model-View-Controller pattern, explaining the basic concepts of the pattern and providing a bit of its history. The chapter goes on to describe the state of the MVC pattern on the web today as it is implemented by various frameworks, such as ASP.NET MVC 2.

Chapter 3 "ASP.NET > ASP.NET MVC" then covers the ways that ASP.NET MVC is different from ASP.NET Web Forms.

Chapter 4 "Routes and URLs" digs deep into routing to describe the role that URLs play in your application and how routing figures into that. It also differentiates routing from URL rewriting and covers a bit on extending routing and writing unit tests for routes.

Chapter 5 "Controllers" takes a look at controllers and controller actions-what they are, and how to write them. It also covers action results, which are returned by controller actions and what they are used for.

Chapters 6 "Views" and 7 "Ajax" cover views and view engines, and then add a little flavor on top by examining the role that AJAX plays in your views.

The second half of the book focuses entirely on advanced techniques and extending the framework.

Chapter 8 "Filters" goes into detail on action filters, which provide an extensibility point for adding cross-cutting behaviors to action methods.

Chapter 9 "Securing Your Application" covers security and good practices for building a secure application.

Chapter 10 "Test Driven Development with ASP.NET MVC" provides a brief introduction to Test Driven Development (TDD) as it applies to ASP.NET MVC.

Chapter 11 "Testable Design Patterns" shows you real-world patterns and practices for building applications that are testable.

Chapter 12 "The Best of Both Worlds: Web Forms and MVC Together" discusses how Web Forms and MVC work together.

Chapter 13 "What's New in ASP.NET MVC 2" covers what's new in MVC 2.

This book is for web developers who are looking to add more complete testing to their web sites, and who are perhaps ready for "something different."

In some places, we assume that you're somewhat familiar with ASP.NET WebForms, at least peripherally. There are a lot of ASP.NET WebForms developers out there who are interested in ASP.NET MVC so there are a number of places in this book where we contrast the two technologies. Even if you're not already an ASP.NET developer, you might still find these sections interesting for context, as well as for your own edification as ASP.NET MVC may not be the web technology that you're looking for.

Table of Contents

  1. Copyright
  2. ABOUT THE AUTHORS
  3. ABOUT THE TECHNICAL EDITORS
  4. CREDITS
  5. ACKNOWLEDGMENTS
  6. FOREWORD
  7. INTRODUCTION
    1. WHO THIS BOOK IS FOR
    2. HOW THIS BOOK IS STRUCTURED
    3. WHAT YOU NEED TO USE THIS BOOK
    4. CONVENTIONS
    5. SOURCE CODE
    6. ERRATA
    7. P2P.WROX.COM
  8. 1. NerdDinner
    1. 1.1. FILE NEW PROJECT
      1. 1.1.1. Examining the NerdDinner Directory Structure
      2. 1.1.2. Running the NerdDinner Application
      3. 1.1.3. Testing the NerdDinner Application
    2. 1.2. CREATING THE DATABASE
      1. 1.2.1. Creating a New SQL Server Express Database
      2. 1.2.2. Creating Tables within Our Database
      3. 1.2.3. Setting Up a Foreign Key Relationship between Tables
      4. 1.2.4. Adding Data to Our Tables
    3. 1.3. BUILDING THE MODEL
      1. 1.3.1. Entity Framework
      2. 1.3.2. Adding Entity Framework Classes to Our Project
      3. 1.3.3. Creating Data Model Classes with Entity Framework
      4. 1.3.4. NerdDinnerEntities Class
      5. 1.3.5. Creating a DinnerRepository Class
      6. 1.3.6. Retrieving, Updating, Inserting, and Deleting Using the DinnerRepository Class
        1. 1.3.6.1. Querying Examples
        2. 1.3.6.2. Insert and Update Examples
        3. 1.3.6.3. Delete Example
      7. 1.3.7. Integrating Validation and Business Rule Logic with Model Classes
        1. 1.3.7.1. Schema Validation
        2. 1.3.7.2. Validation and Business Rule Logic
    4. 1.4. CONTROLLERS AND VIEWS
      1. 1.4.1. Adding a DinnersController Controller
      2. 1.4.2. Adding Index and Details Action Methods to the DinnersController Class
      3. 1.4.3. Understanding ASP.NET MVC Routing
      4. 1.4.4. Using the DinnerRepository from Our DinnersController
      5. 1.4.5. Using Views with Our Controller
      6. 1.4.6. Implementing the "NotFound" View Template
      7. 1.4.7. Implementing the "Details" View Template
      8. 1.4.8. Implementing the "Index" View Template
      9. 1.4.9. Convention-Based Naming and the \Views Directory Structure
    5. 1.5. CREATE, UPDATE, DELETE FORM SCENARIOS
      1. 1.5.1. URLs Handled by DinnersController
      2. 1.5.2. Implementing the HTTP-GET Edit Action Method
      3. 1.5.3. Html.BeginForm and Html.TextBoxFor Html Helper Methods
        1. 1.5.3.1. Html.BeginForm Helper Method
        2. 1.5.3.2. Html.TextBoxFor Helper Method
      4. 1.5.4. Implementing the HTTP-POST Edit Action Method
        1. 1.5.4.1. Retrieving Form Post Values
      5. 1.5.5. Handling Edit Errors
      6. 1.5.6. Understanding ModelState and the Validation HTML Helper Methods
        1. 1.5.6.1. HTML Helper Integration with ModelState
        2. 1.5.6.2. Html .ValidationMessageFor Helper Method
        3. 1.5.6.3. Html.ValidationSummary Helper Method
      7. 1.5.7. Complete Edit Action Method Implementations
      8. 1.5.8. Implementing the HTTP-GET Create Action Method
      9. 1.5.9. Implementing the HTTP-POST Create Action Method
      10. 1.5.10. Implementing the HTTP-GET Delete Action Method
      11. 1.5.11. Implementing the HTTP-POST Delete Action Method
      12. 1.5.12. Model Binding Security
        1. 1.5.12.1. Locking Down Binding on a Per-Usage Basis
        2. 1.5.12.2. Locking Down Binding on a Type Basis
      13. 1.5.13. CRUD Wrap-Up
    6. 1.6. VIEWDATA AND VIEWMODEL
      1. 1.6.1. Passing Data from Controllers to View Templates
      2. 1.6.2. Using the ViewData Dictionary
      3. 1.6.3. Using a ViewModel Pattern
      4. 1.6.4. Custom-Shaped ViewModel Classes
    7. 1.7. PARTIALS AND MASTER PAGES
      1. 1.7.1. Revisiting Our Edit and Create View Templates
      2. 1.7.2. Using Partial View Templates
      3. 1.7.3. Using Partial View Templates to Clarify Code
      4. 1.7.4. Master Pages
    8. 1.8. PAGING SUPPORT
      1. 1.8.1. Index Action Method Recap
      2. 1.8.2. Understanding IQueryable<T>
      3. 1.8.3. Adding a page Value to the URL
        1. 1.8.3.1. Using a Querystring Value
        2. 1.8.3.2. Using Embedded URL Values
      4. 1.8.4. Adding Page Navigation UI
    9. 1.9. AUTHENTICATION AND AUTHORIZATION
      1. 1.9.1. Understanding Authentication and Authorization
      2. 1.9.2. Forms Authentication and the AccountController
      3. 1.9.3. Authorizing the /Dinners/Create URL Using the [Authorize] Filter
      4. 1.9.4. Using the User.Identity.Name Property When Creating Dinners
      5. 1.9.5. Using the User.Identity.Name Property When Editing Dinners
      6. 1.9.6. Showing/Hiding Edit and Delete Links
    10. 1.10. AJAX ENABLING RSVPS ACCEPTS
      1. 1.10.1. Indicating Whether the User Is RSVP'ed
      2. 1.10.2. Implementing the Register Action Method
      3. 1.10.3. Calling the Register Action Method Using AJAX
      4. 1.10.4. Adding a jQuery Animation
      5. 1.10.5. Cleanup — Refactor Out a RSVP Partial View
    11. 1.11. INTEGRATING AN AJAX MAP
      1. 1.11.1. Creating a Map Partial View
      2. 1.11.2. Creating a Map.js Utility Library
      3. 1.11.3. Integrating the Map with Create and Edit Forms
      4. 1.11.4. Integrating the Map with the Details View
      5. 1.11.5. Implementing Location Search in Our Database and Repository
      6. 1.11.6. Implementing a JSON-Based AJAX Search Action Method
      7. 1.11.7. Calling the JSON-Based AJAX Method Using jQuery
    12. 1.12. UNIT TESTING
      1. 1.12.1. Why Unit Test?
      2. 1.12.2. NerdDinner.Tests Project
      3. 1.12.3. Creating Unit Tests for Our Dinner Model Class
      4. 1.12.4. Running Tests
      5. 1.12.5. Creating DinnersController Unit Tests
      6. 1.12.6. Dependency Injection
      7. 1.12.7. Extracting an IDinnerRepository Interface
      8. 1.12.8. Updating DinnersController to Support Constructor Injection
      9. 1.12.9. Creating the FakeDinnerRepository Class
      10. 1.12.10. Using the FakeDinnerRepository with Unit Tests
      11. 1.12.11. Creating Edit Action Unit Tests
      12. 1.12.12. Mocking the User.Identity.Name Property
      13. 1.12.13. Testing UpdateModel Scenarios
      14. 1.12.14. Testing Wrap-Up
    13. 1.13. NERDDINNER WRAP-UP
  9. 2. Model-View-Controller and ASP.NET
    1. 2.1. WHAT IS MODEL-VIEW-CONTROLLER?
    2. 2.2. MVC ON THE WEB TODAY
      1. 2.2.1. Ruby on Rails
      2. 2.2.2. Django and Python
      3. 2.2.3. Spring, Struts, and Java
      4. 2.2.4. Zend Framework and PHP
      5. 2.2.5. MonoRail
    3. 2.3. ASP.NET MVC: THE NEW KID ON THE BLOCK
      1. 2.3.1. Serving Methods, Not Files
      2. 2.3.2. Is This Web Forms 4.0?
      3. 2.3.3. Why Not Web Forms?
      4. 2.3.4. Cost/Benefit of Web Forms
      5. 2.3.5. Should You Fear ASP.NET MVC?
        1. 2.3.5.1. It's the End of Web Forms!
        2. 2.3.5.2. It's Totally Different!
    4. 2.4. SUMMARY
  10. 3. ASP.NET > ASP.NET MVC
    1. 3.1. ABSTRACTION: WHAT WEB FORMS DOES WELL
      1. 3.1.1. A Basic Web Forms Application
      2. 3.1.2. The Importance of Events
    2. 3.2. THE LEAK: WHERE WEB FORMS DOESN'T EXACTLY FIT
      1. 3.2.1. ViewState
      2. 3.2.2. Controlling Your Angle Brackets
      3. 3.2.3. Client IDs
      4. 3.2.4. Testing
    3. 3.3. BACK TO BASICS: ASP.NET MVC BELIEVES...
      1. 3.3.1. Orchestration versus Composing
      2. 3.3.2. Separation of Concerns: What It Means
      3. 3.3.3. Approaches to Maintainability
    4. 3.4. CARING ABOUT TESTABILITY
    5. 3.5. COMMON REACTIONS TO ASP.NET MVC
      1. 3.5.1. This Looks Like Classic ASP from 1999!
      2. 3.5.2. Who Moved My <asp:Cheese runat="server"}>?
      3. 3.5.3. Yet Another Web Framework
    6. 3.6. WHY "(ASP.NET > ASP.NET MVC) == TRUE"
      1. 3.6.1. Convention over Configuration
      2. 3.6.2. Your First, er, Third, Request
      3. 3.6.3. The Request Life Cycle
    7. 3.7. SUMMARY
  11. 4. Routes and URLs
    1. 4.1. INTRODUCTION TO ROUTING
      1. 4.1.1. Compared to URL Rewriting
      2. 4.1.2. Defining Routes
        1. 4.1.2.1. Route URLs
        2. 4.1.2.2. Defaults
        3. 4.1.2.3. Constraints
      3. 4.1.3. Named Routes
      4. 4.1.4. Areas
        1. 4.1.4.1. Area Route Registration
        2. 4.1.4.2. Area Route Conflicts
      5. 4.1.5. Catch-All Parameter
      6. 4.1.6. StopRoutingHandler and IgnoreRoute
      7. 4.1.7. Debugging Routes
      8. 4.1.8. Under the Hood: How Routes Generate URLs
        1. 4.1.8.1. High-Level View of URL Generation
        2. 4.1.8.2. Detailed Look at URL Generation
        3. 4.1.8.3. Named Routes
        4. 4.1.8.4. Ambient Values
        5. 4.1.8.5. Ambient Values and Default Values without Corresponding URL Parameter
        6. 4.1.8.6. Overflow Parameters
        7. 4.1.8.7. More Examples of URL Generation with the Route Class
    2. 4.2. UNDER THE HOOD: HOW ROUTES TIE YOUR URL TO AN ACTION
      1. 4.2.1. The High-Level Request Routing Pipeline
      2. 4.2.2. Route Matching
        1. 4.2.2.1. RouteData
    3. 4.3. ADVANCED ROUTING WITH CUSTOM CONSTRAINTS
    4. 4.4. ROUTE EXTENSIBILITY
      1. 4.4.1. Editable Routes
    5. 4.5. USING ROUTING WITH WEB FORMS
      1. 4.5.1. Routing With Web Forms in ASP.NET 4
      2. 4.5.2. Routing with Web Forms in ASP.NET 3.5
    6. 4.6. SUMMARY
  12. 5. Controllers
    1. 5.1. HISTORY OF THE CONTROLLER
    2. 5.2. DEFINING THE CONTROLLER: THE ICONTROLLER INTERFACE
    3. 5.3. THE CONTROLLERBASE ABSTRACT BASE CLASS
    4. 5.4. THE CONTROLLER CLASS AND ACTIONS
      1. 5.4.1. Action Methods
        1. 5.4.1.1. Working with Parameters
        2. 5.4.1.2. Working with Multiple Parameters
        3. 5.4.1.3. Default Parameters
    5. 5.5. THE ACTIONRESULT
      1. 5.5.1. Action Result Types
        1. 5.5.1.1. EmptyResult
        2. 5.5.1.2. ContentResult
        3. 5.5.1.3. FileResult
        4. 5.5.1.4. JsonResult
        5. 5.5.1.5. JavaScriptResult
        6. 5.5.1.6. RedirectResult
        7. 5.5.1.7. RedirectToRouteResult
        8. 5.5.1.8. ViewResult
        9. 5.5.1.9. PartialViewResult
      2. 5.5.2. Action Result Helper Methods
      3. 5.5.3. Implicit Action Results
    6. 5.6. ACTION INVOKER
      1. 5.6.1. How an Action Is Mapped to a Method
        1. 5.6.1.1. Action Method Selection
        2. 5.6.1.2. ActionNameAttribute
        3. 5.6.1.3. ActionSelectorAttribute
        4. 5.6.1.4. AcceptVerbsAttribute
        5. 5.6.1.5. Simulating RESTful Verbs
      2. 5.6.2. Mapping Parameters
      3. 5.6.3. Invoking Actions
      4. 5.6.4. Using Asynchronous Controller Actions
        1. 5.6.4.1. Choosing Synchronous versus Asynchronous Pipelines
        2. 5.6.4.2. Writing Asynchronous Action Methods
        3. 5.6.4.3. The MVC Pattern for Asynchronous Actions
        4. 5.6.4.4. Performing Multiple Parallel Operations
        5. 5.6.4.5. Using Filters with Asynchronous Controller Actions
        6. 5.6.4.6. Timeouts
        7. 5.6.4.7. Additional Considerations for Asynchronous Methods
      5. 5.6.5. Passing Data to Actions: The Model Binders
        1. 5.6.5.1. Using UpdateModel to Update the Model
        2. 5.6.5.2. Validation with Data Annotations
      6. 5.6.6. A Word about User Input
    7. 5.7. SUMMARY
  13. 6. Views
    1. 6.1. WHAT A VIEW DOES
    2. 6.2. WHAT A VIEW SHOULDN'T DO
    3. 6.3. SPECIFYING A VIEW
    4. 6.4. STRONGLY TYPED VIEWS
    5. 6.5. VIEWMODELS
    6. 6.6. HTML HELPER METHODS
      1. 6.6.1. HtmlHelper Class and Extension Methods
      2. 6.6.2. Using the HTML Helpers
        1. 6.6.2.1. Strongly Typed HTML Helpers
        2. 6.6.2.2. Html.Encode
        3. 6.6.2.3. Html.TextBox
        4. 6.6.2.4. Html.ActionLink and Html.RouteLink
        5. 6.6.2.5. Html.BeginForm
        6. 6.6.2.6. Html.Hidden
        7. 6.6.2.7. Html.DropDownList and Html.ListBox
        8. 6.6.2.8. Html.Password
        9. 6.6.2.9. Html.RadioButton
        10. 6.6.2.10. Html.Partial and Html.RenderPartial
        11. 6.6.2.11. Html.Action and Html.RenderAction
          1. 6.6.2.11.1. Passing Values With RenderAction
          2. 6.6.2.11.2. Cooperating with the ActionName attribute
        12. 6.6.2.12. Html.TextArea
        13. 6.6.2.13. Html.ValidationMessage
        14. 6.6.2.14. Html.ValidationSummary
      3. 6.6.3. HTML Template Customization
    7. 6.7. THE VIEW ENGINE
      1. 6.7.1. Configuring a View Engine
      2. 6.7.2. Finding a View
      3. 6.7.3. The View Itself
      4. 6.7.4. Alternative View Engines
        1. 6.7.4.1. Spark
        2. 6.7.4.2. NHaml
        3. 6.7.4.3. NVelocity
        4. 6.7.4.4. Brail
    8. 6.8. NEW VIEW ENGINE OR NEW ACTIONRESULT?
    9. 6.9. SUMMARY
  14. 7. AJAX
    1. 7.1. WHEN AJAX IS COOL
    2. 7.2. WHEN IT'S NOT
    3. 7.3. AJAX EXAMPLES
      1. 7.3.1. Handling Disabled Scripting
      2. 7.3.2. Using Partials for Rendering
      3. 7.3.3. Some Things You May Not Know about Microsoft ASP.NET Ajax
      4. 7.3.4. How It Works
        1. 7.3.4.1. Script #
      5. 7.3.5. Updating an HTML Element When Submitting a Form
      6. 7.3.6. The AutoComplete TextBox
      7. 7.3.7. Implementing AutoComplete with Microsoft ASP.NET Ajax
      8. 7.3.8. Filtering Data with a Selectbox
      9. 7.3.9. The Modal Pop-Up with jQuery
      10. 7.3.10. The Modal Pop-Up Code
      11. 7.3.11. The Rating Control
    4. 7.4. SUMMARY
  15. 8. Filters
    1. 8.1. FILTERS INCLUDED WITH ASP.NET MVC
      1. 8.1.1. Authorize
      2. 8.1.2. RequireHttps
      3. 8.1.3. OutputCache
        1. 8.1.3.1. API
        2. 8.1.3.2. Difference with the @OutputCache Directive
        3. 8.1.3.3. Usage Examples
      4. 8.1.4. Exception Filter
      5. 8.1.5. Custom Filters
        1. 8.1.5.1. ActionFilterAttribute
        2. 8.1.5.2. Action Filter Contexts
        3. 8.1.5.3. ActionExecutingContext
        4. 8.1.5.4. ActionExecutedContext
        5. 8.1.5.5. ResultExecutingContext
        6. 8.1.5.6. ResultExecutedContext
    2. 8.2. WRITING A CUSTOM ACTION FILTER
    3. 8.3. WRITING A CUSTOM AUTHORIZATION FILTER
    4. 8.4. WRITING A CUSTOM EXCEPTION FILTER
    5. 8.5. FILTER ORDERING
    6. 8.6. FILTER NAMING
    7. 8.7. SUMMARY
  16. 9. Securing Your Application
    1. 9.1. THIS IS A WAR
      1. 9.1.1. What Do Hackers Want?
      2. 9.1.2. How Do They Get It?
        1. 9.1.2.1. Case Study: DEFCON's Capture the Flag
        2. 9.1.2.2. Case Study: Deception and Hacking into the Server Room
        3. 9.1.2.3. Case Study: Social Engineering and Kevin Mitnick
    2. 9.2. WEAPONS
      1. 9.2.1. Spam
      2. 9.2.2. Case Study: Profiting from Evil with the Srizbi and Storm Botnets
        1. 9.2.2.1. The Storm Worm
        2. 9.2.2.2. The Srizbi Trojan
        3. 9.2.2.3. The Conficker Worm
      3. 9.2.3. Digital Stealth Ninja Network
    3. 9.3. THREAT: CROSS-SITE SCRIPTING (XSS)
      1. 9.3.1. Threat Summary
        1. 9.3.1.1. Passive Injection
        2. 9.3.1.2. Active Injection
      2. 9.3.2. Preventing XSS
        1. 9.3.2.1. HTML Encode All Content
        2. 9.3.2.2. Html.AttributeEncode and Url.Encode
        3. 9.3.2.3. JavaScript Encoding
        4. 9.3.2.4. Using AntiXSS as the Default Encoder for ASP.NET
    4. 9.4. THREAT: CROSS-SITE REQUEST FORGERY
      1. 9.4.1. Threat Summary
      2. 9.4.2. Preventing CSRF Attacks
        1. 9.4.2.1. Token Verification
        2. 9.4.2.2. Idempotent GETs
        3. 9.4.2.3. HttpReferrer Validation
    5. 9.5. THREAT: COOKIE STEALING
      1. 9.5.1. Threat Summary
      2. 9.5.2. Preventing Cookie Theft with HttpOnly
    6. 9.6. THREAT: OVER-POSTING
      1. 9.6.1. Threat Summary
      2. 9.6.2. Preventing Over-Posting with the Bind Attribute
    7. 9.7. KEEPING YOUR PANTS UP: PROPER ERROR REPORTING AND THE STACK TRACE
    8. 9.8. SECURING YOUR CONTROLLERS, NOT YOUR ROUTES
      1. 9.8.1. Using [Authorize] to Lock Down Your Action or Controller
      2. 9.8.2. Using [NonAction] to Protect Public Methods
    9. 9.9. SUMMARY: IT'S UP TO YOU
  17. 10. Test Driven Development with ASP.NET MVC
    1. 10.1. A BRIEF INTRODUCTION TO TDD
      1. 10.1.1. What Does TDD Look Like?
        1. 10.1.1.1. Write a Unit Test That Fails
        2. 10.1.1.2. Write Just Enough Code to Make the Test Pass
        3. 10.1.1.3. Refactor the Code
        4. 10.1.1.4. Repeat
      2. 10.1.2. Writing Good Unit Tests
        1. 10.1.2.1. Tests Should Not Cross Boundaries
        2. 10.1.2.2. Default Unit Tests
        3. 10.1.2.3. Only Test the Code That You Write
      3. 10.1.3. What Are Some Benefits of Writing Tests?
      4. 10.1.4. How Do I Get Started?
    2. 10.2. APPLYING TDD TO ASP.NET MVC
      1. 10.2.1. Testing Routes
      2. 10.2.2. Testing Controllers
      3. 10.2.3. Redirecting to Another Action
      4. 10.2.4. Testing View Helpers
      5. 10.2.5. Testing Views
    3. 10.3. SUMMARY
  18. 11. Testable Design Patterns
    1. 11.1. WHY YOU SHOULD CARE ABOUT TESTABILITY
      1. 11.1.1. Big Design Up Front (BDUF)
        1. 11.1.1.1. General Process
        2. 11.1.1.2. Testability Considerations
      2. 11.1.2. Agile Software Development
        1. 11.1.2.1. General Process
        2. 11.1.2.2. Testability Considerations
    2. 11.2. YOU WANT TO WRITE TESTABLE CODE
    3. 11.3. USING TESTS TO PROVE YOU'RE DONE
    4. 11.4. DESIGNING YOUR APPLICATION FOR TESTABILITY
      1. 11.4.1. Future-Proofing Your Application with Interfaces
      2. 11.4.2. The Single Responsibility Principle
      3. 11.4.3. Avoid Using Singletons and Static Methods
        1. 11.4.3.1. Singletons and Tight Coupling
        2. 11.4.3.2. The Myth of Singleton Performance
        3. 11.4.3.3. Static Methods and Global Variables
    5. 11.5. TESTABLE DATA ACCESS
      1. 11.5.1. Creating the Model
      2. 11.5.2. The Repository Pattern in Detail
        1. 11.5.2.1. The Northwind Product Repository
        2. 11.5.2.2. Implementing a Repository Stub
        3. 11.5.2.3. Implementing the Real Thing with Integration Tests
    6. 11.6. IMPLEMENTING BUSINESS LOGIC WITH THE SERVICE LAYER
      1. 11.6.1. Services Gone Wild
      2. 11.6.2. Partial Solution: Setting Controller Dependencies Manually
        1. 11.6.2.1. Best Solution: Using Dependency Injection
        2. 11.6.2.2. Dependency Injection with StructureMap
    7. 11.7. SUMMARY
  19. 12. Best of Both Worlds: Web Forms and MVC Together
    1. 12.1. HOW IS IT POSSIBLE?
    2. 12.2. INCLUDING MVC IN EXISTING WEB FORMS APPLICATIONS
      1. 12.2.1. Step 1: Referencing the Required Libraries
      2. 12.2.2. Step 2: Creating the Necessary Directories
      3. 12.2.3. Step 3: Updating the Web.config
    3. 12.3. ADDING WEB FORMS TO AN EXISTING ASP.NET MVC APPLICATION
      1. 12.3.1. The Easy Part: Do Nothing
      2. 12.3.2. When/Home/Isn't/Home/
      3. 12.3.3. Using System.Web.Routing to Route to Web Forms
    4. 12.4. SHARING DATA BETWEEN WEB FORMS AND MVC
      1. 12.4.1. Using Route Parameters
      2. 12.4.2. Using HTTP-POST
      3. 12.4.3. Using the ASP.NET Session
      4. 12.4.4. Using Cross-Page Posting
      5. 12.4.5. Using TempData
    5. 12.5. MIGRATING FROM WEB FORMS TO MVC
      1. 12.5.1. Step 1: Create an Empty ASP.NET MVC Project with a Test Project
      2. 12.5.2. Step 2: Implement the Structure
      3. 12.5.3. Step 3: Add Images and Styling
      4. 12.5.4. Step 4: Set Up Routing and Controllers
        1. 12.5.4.1. Setting Up the Routing
        2. 12.5.4.2. The ClubSiteMVC Controllers
      5. 12.5.5. Step 5: Replace Complex Server Controls
        1. 12.5.5.1. Options for Control Replacement
        2. 12.5.5.2. Not Invented Here?
      6. 12.5.6. Step 6: Upload Files and Work with Images
        1. 12.5.6.1. Taking a Step Back
        2. 12.5.6.2. Using HttpRequest
    6. 12.6. SUMMARY
  20. 13. What's New in ASP.NET MVC 2
    1. 13.1. SECURITY
      1. 13.1.1. HTML Encoding Code Blocks
      2. 13.1.2. JsonResult
    2. 13.2. PRODUCTIVITY
      1. 13.2.1. Strongly Typed HTML Helpers
      2. 13.2.2. Templated Helpers
        1. 13.2.2.1. Templated Helper Methods and Conventions
        2. 13.2.2.2. Example: Using a DateTime Editor Template
      3. 13.2.3. Model Validation
        1. 13.2.3.1. Defining Validation Rules with Data Annotations
      4. 13.2.4. Client-Side Validation
      5. 13.2.5. Model Metadata
      6. 13.2.6. Html.Action and Html.RenderAction
      7. 13.2.7. Code Snippets in Views
      8. 13.2.8. Organize Projects with Areas
    3. 13.3. PERFORMANCE: ASYNCHRONOUS CONTROLLER ACTIONS
    4. 13.4. MISCELLANEOUS
    5. 13.5. SUMMARY