21
Steven Sanderson Pro ASP.NET MVC Framework

Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

  • Upload
    dokhue

  • View
    229

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Steven Sanderson

Pro ASP.NET MVCFramework

Page 2: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Pro ASP.NET MVC Framework

Copyright © 2009 by Steven Sanderson

All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means,electronic or mechanical, including photocopying, recording, or by any information storage or retrievalsystem, without the prior written permission of the copyright owner and the publisher.

ISBN-13 (pbk): 978-1-4302-1007-8

ISBN-13 (electronic): 978-1-4302-1008-5

Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1

Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrenceof a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademarkowner, with no intention of infringement of the trademark.

Lead Editor: Ewan BuckinghamTechnical Reviewer: Andy OlsenEditorial Board: Clay Andres, Steve Anglin, Mark Beckner, Ewan Buckingham, Tony Campbell,

Gary Cornell, Jonathan Gennick, Jonathan Hassell, Michelle Lowman, Matthew Moodie, Duncan Parkes,Jeffrey Pepper, Frank Pohlmann, Ben Renow-Clarke, Dominic Shakeshaft, Matt Wade, Tom Welsh

Project Manager: Sofia MarchantCopy Editor: Damon LarsonAssociate Production Director: Kari Brooks-CoponyProduction Editor: Laura EstermanCompositor: Molly SharpProofreader: Lisa HamiltonIndexer: BIM Indexing and Proofreading ServicesArtist: April MilneCover Designer: Kurt KramesManufacturing Director: Tom Debolski

Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor,New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail [email protected],or visit http://www.springeronline.com.

For information on translations, please contact Apress directly at 2855 Telegraph Avenue, Suite 600,Berkeley, CA 94705. Phone 510-549-5930, fax 510-549-5939, e-mail [email protected], or visithttp://www.apress.com.

Apress and friends of ED books may be purchased in bulk for academic, corporate, or promotional use.eBook versions and licenses are also available for most titles. For more information, reference our SpecialBulk Sales–eBook Licensing web page at http://www.apress.com/info/bulksales.

The information in this book is distributed on an “as is” basis, without warranty. Although every precaution has been taken in the preparation of this work, neither the author(s) nor Apress shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be causeddirectly or indirectly by the information contained in this work.

The source code for this book is available to readers at http://www.apress.com.

Page 3: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

For Zoe, without whose love, support, and hard work this project would not have been possible. Thank you!

Page 4: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Contents at a Glance

About the Author. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii

About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix

Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx

Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi

PART 1 ■ ■ ■ Introducing ASP.NET MVC■CHAPTER 1 What’s the Big Idea? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

■CHAPTER 2 Your First ASP.NET MVC Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

■CHAPTER 3 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

■CHAPTER 4 SportsStore: A Real Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

■CHAPTER 5 SportsStore: Navigation and Shopping Cart . . . . . . . . . . . . . . . . . . . . 121

■CHAPTER 6 SportsStore: Administration and Final Enhancements . . . . . . . . . . 171

PART 2 ■ ■ ■ ASP.NET MVC in Detail■CHAPTER 7 Overview of ASP.NET MVC Projects. . . . . . . . . . . . . . . . . . . . . . . . . . . . 203

■CHAPTER 8 URLs and Routing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

■CHAPTER 9 Controllers and Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259

■CHAPTER 10 Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321

■CHAPTER 11 Data Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369

■CHAPTER 12 Ajax and Client Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419

■CHAPTER 13 Security and Vulnerability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459

■CHAPTER 14 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477

■CHAPTER 15 ASP.NET Platform Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505

■CHAPTER 16 Combining MVC and WebForms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555

■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573

v

Page 5: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Contents

About the Author. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii

About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix

Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx

Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi

PART 1 ■ ■ ■ Introducing ASP.NET MVC

■CHAPTER 1 What’s the Big Idea?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

A Brief History of Web Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Traditional ASP.NET. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

What’s Wrong with Traditional ASP.NET? . . . . . . . . . . . . . . . . . . . . . . . 4

Web Development Today . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Web Standards and REST. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

Agile and Test-Driven Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

Ruby on Rails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

Key Benefits of ASP.NET MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

Model-View-Controller Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

Extensibility. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Testability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Tight Control over HTML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Powerful New Routing System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Built on the Best Parts of the ASP.NET Platform . . . . . . . . . . . . . . . . . 9

.NET 3.5 Language Innovations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

ASP.NET MVC Is Open Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Who Should Use ASP.NET MVC?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Comparisons with ASP.NET WebForms . . . . . . . . . . . . . . . . . . . . . . . . 11

Comparisons with Ruby on Rails. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Comparisons with MonoRail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

vii

Page 6: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

■CHAPTER 2 Your First ASP.NET MVC Application . . . . . . . . . . . . . . . . . . . . . . 15

Preparing Your Workstation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

Creating a New ASP.NET MVC Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Removing Unnecessary Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

How Does It Work? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Rendering Web Pages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Creating and Rendering a View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Adding Dynamic Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

A Starter Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

The Story . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

Linking Between Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

Designing a Data Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

Building a Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

Handling Form Submissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

Adding Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Finishing Off . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

■CHAPTER 3 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

Understanding Model-View-Controller Architecture . . . . . . . . . . . . . . . . . . 37

The Smart UI (Anti-Pattern) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Separating Out the Domain Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

Three-Tier Architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

Model-View-Controller Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

Variations on Model-View-Controller . . . . . . . . . . . . . . . . . . . . . . . . . . 43

Domain Modeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

An Example Domain Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

Entities and Value Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

Ubiquitous Language. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

Aggregates and Simplification. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

Keeping Data Access Code in Repositories. . . . . . . . . . . . . . . . . . . . . 48

Using LINQ to SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Building Loosely Coupled Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

Taking a Balanced Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Using Inversion of Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Using an IoC Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Getting Started with Automated Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

Unit Tests and Integration Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

The Red-Green Development Style. . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

■CONTENTSviii

Page 7: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

New C# 3 Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

The Design Goal: Language Integrated Query . . . . . . . . . . . . . . . . . . 68

Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

Lambda Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

Generic Type Inference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Automatic Properties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Object and Collection Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Type Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

Anonymous Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

Using LINQ to Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

IQueryable<T> and LINQ to SQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

■CHAPTER 4 SportsStore: A Real Application. . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Getting Started. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

Creating Your Solutions and Projects . . . . . . . . . . . . . . . . . . . . . . . . . . 83

Starting Your Domain Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Creating an Abstract Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Making a Fake Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

Displaying a List of Products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

Removing Unnecessary Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

Adding the First Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

Setting Up the Default Route . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

Adding the First View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

Connecting to a Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

Defining the Database Schema. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

Setting Up LINQ to SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

Creating a Real Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

Setting Up Inversion of Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

Creating a Custom Controller Factory . . . . . . . . . . . . . . . . . . . . . . . . . 97

Using Your IoC Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

Creating Automated Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

Configuring a Custom URL Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

Adding a RouteTable Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

Displaying Page Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

Styling It Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

Defining Page Layout in the Master Page . . . . . . . . . . . . . . . . . . . . . 114

Adding CSS Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

Creating a Partial View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

■CONTENTS ix

Page 8: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

■CHAPTER 5 SportsStore: Navigation and Shopping Cart. . . . . . . . . . . . . . 121

Adding Navigation Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

Filtering the Product List. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

Defining a URL Schema for Categories . . . . . . . . . . . . . . . . . . . . . . . 125

Building a Category Navigation Menu . . . . . . . . . . . . . . . . . . . . . . . . 131

Building the Shopping Cart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

Defining the Cart Entity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141

Adding “Add to Cart” Buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

Giving Each Visitor a Separate Shopping Cart . . . . . . . . . . . . . . . . . 146

Creating CartController . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

Displaying the Cart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150

Removing Items from the Cart. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

Displaying a Cart Summary in the Title Bar . . . . . . . . . . . . . . . . . . . 154

Submitting Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

Enhancing the Domain Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

Adding the “Check Out Now” Button . . . . . . . . . . . . . . . . . . . . . . . . . 159

Prompting the Customer for Shipping Details. . . . . . . . . . . . . . . . . . 159

Defining an Order Submitter IoC Component . . . . . . . . . . . . . . . . . . 161

Completing CartController . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

Implementing the EmailOrderSubmitter. . . . . . . . . . . . . . . . . . . . . . . 167

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

■CHAPTER 6 SportsStore: Administration and Final Enhancements . . . 171

Adding Catalog Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

Creating AdminController: A Place for the CRUD Features . . . . . . . 172

Rendering a Grid of Products in the Repository . . . . . . . . . . . . . . . . 175

Building a Product Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

Creating New Products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

Deleting Products. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187

Securing the Administration Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188

Setting Up Forms Authentication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189

Using a Filter to Enforce Authentication. . . . . . . . . . . . . . . . . . . . . . . 190

Displaying a Login Prompt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191

Image Uploads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195

Preparing the Domain Model and Database . . . . . . . . . . . . . . . . . . . 195

Accepting File Uploads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196

Displaying Product Images. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197

Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

■CONTENTSx

Page 9: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

PART 2 ■ ■ ■ ASP.NET MVC in Detail

■CHAPTER 7 Overview of ASP.NET MVC Projects . . . . . . . . . . . . . . . . . . . . . . . 203

Developing MVC Applications in Visual Studio . . . . . . . . . . . . . . . . . . . . . . 203

The Default MVC Project Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

The Initial Application Skeleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208

Debugging MVC Applications and Unit Tests . . . . . . . . . . . . . . . . . . 208

Using the Debugger. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

Stepping into the .NET Framework Source Code . . . . . . . . . . . . . . . 212

Stepping into the ASP.NET MVC Source Code . . . . . . . . . . . . . . . . . 213

The Request Processing Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

Stage 1: IIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

Stage 2: Core Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

Stage 3: Controllers and Actions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

Stage 4: Action Results and Views . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

■CHAPTER 8 URLs and Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

Putting the Programmer Back in Control. . . . . . . . . . . . . . . . . . . . . . . . . . . 221

Setting Up Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

Understanding the Routing Mechanism. . . . . . . . . . . . . . . . . . . . . . . 224

Adding a Route Entry. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

Using Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

Using Defaults . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229

Using Constraints. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230

Accepting a Variable-Length List of Parameters . . . . . . . . . . . . . . . 233

Matching Files on the Server’s Hard Disk . . . . . . . . . . . . . . . . . . . . . 234

Using IgnoreRoute to Bypass the Routing System . . . . . . . . . . . . . . 235

Generating Outgoing URLs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

Generating Hyperlinks with Html.ActionLink. . . . . . . . . . . . . . . . . . . 237

Generating Links and URLs from Pure Routing Data . . . . . . . . . . . . 239

Performing Redirections to Generated URLs. . . . . . . . . . . . . . . . . . . 240

Understanding the Outbound URL-Matching Algorithm . . . . . . . . . 241

Generating Hyperlinks with Html.ActionLink<T> and Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243

Working with Named Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244

■CONTENTS xi

Page 10: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Unit Testing Your Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

Testing Inbound URL Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

Testing Outbound URL Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . 249

Further Customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

Implementing a Custom RouteBase Entry . . . . . . . . . . . . . . . . . . . . . 251

Implementing a Custom Route Handler . . . . . . . . . . . . . . . . . . . . . . . 252

URL Schema Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253

Make Your URLs Clean and Human-Friendly . . . . . . . . . . . . . . . . . . 254

Follow HTTP Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

Search Engine Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258

■CHAPTER 9 Controllers and Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259

An Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259

Comparisons with ASP.NET WebForms . . . . . . . . . . . . . . . . . . . . . . . 260

All Controllers Implement IController . . . . . . . . . . . . . . . . . . . . . . . . . 260

The Controller Base Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

Receiving Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262

Getting Data from Context Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 262

Using Action Method Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264

Invoking Model Binding Manually in an Action Method. . . . . . . . . . 265

Producing Output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266

Understanding the ActionResult Concept . . . . . . . . . . . . . . . . . . . . . 266

Returning HTML by Rendering a View . . . . . . . . . . . . . . . . . . . . . . . . 269

Performing Redirections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273

Returning Textual Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277

Returning JSON Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279

Returning JavaScript Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279

Returning Files and Binary Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

Creating a Custom Action Result Type. . . . . . . . . . . . . . . . . . . . . . . . 283

Using Filters to Attach Reusable Behaviors . . . . . . . . . . . . . . . . . . . . . . . . 286

Introducing the Four Basic Types of Filters . . . . . . . . . . . . . . . . . . . . 286

Applying Filters to Controllers and Action Methods . . . . . . . . . . . . . 288

Creating Action Filters and Result Filters. . . . . . . . . . . . . . . . . . . . . . 289

Creating and Using Authorization Filters . . . . . . . . . . . . . . . . . . . . . . 293

Creating and Using Exception Filters . . . . . . . . . . . . . . . . . . . . . . . . . 296

Bubbling Exceptions Through Action and Result Filters . . . . . . . . . 299

The [OutputCache] Action Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300

Other Built-In Filter Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302

■CONTENTSxii

Page 11: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Controllers As Part of the Request Processing Pipeline . . . . . . . . . . . . . . 303

Working with DefaultControllerFactory . . . . . . . . . . . . . . . . . . . . . . . 303

Creating a Custom Controller Factory . . . . . . . . . . . . . . . . . . . . . . . . 305

Customizing How Action Methods Are Selected and Invoked . . . . 306

Testing Controllers and Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312

How to Arrange, Act, and Assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313

Testing a Choice of View and ViewData. . . . . . . . . . . . . . . . . . . . . . . 313

Testing Redirections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315

More Comments About Testing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316

Mocking Context Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320

■CHAPTER 10 Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321

How Views Fit into ASP.NET MVC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321

The WebForms View Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322

View Engines Are Replaceable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323

WebForms View Engine Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323

Adding Content to a View Template . . . . . . . . . . . . . . . . . . . . . . . . . . 323

Five Ways to Add Dynamic Content to a View Template. . . . . . . . . 323

Using Inline Code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324

Why Inline Code Is a Good Thing in MVC View Templates . . . . . . . 326

Understanding How MVC Views Actually Work . . . . . . . . . . . . . . . . . . . . . 326

Understanding How ASPX Templates Are Compiled . . . . . . . . . . . . 327

Understanding ViewData . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329

Rendering ViewData Items Using ViewData.Eval . . . . . . . . . . . . . . . 330

Using HTML Helper Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

The Framework’s Built-In Helper Methods . . . . . . . . . . . . . . . . . . . . 333

Creating Your Own HTML Helper Methods . . . . . . . . . . . . . . . . . . . . 342

Using Partial Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344

Creating a Partial View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344

Rendering a Partial View Using Server Tags . . . . . . . . . . . . . . . . . . . 349

Using Html.RenderAction to Create Reusable Widgets with Application Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351

What Html.RenderAction Does . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352

When It’s Appropriate to Use Html.RenderAction. . . . . . . . . . . . . . . 352

Creating a Widget Based on Html.RenderAction . . . . . . . . . . . . . . . 353

Sharing Page Layouts Using Master Pages . . . . . . . . . . . . . . . . . . . . . . . . 355

Using Widgets in MVC View Master Pages . . . . . . . . . . . . . . . . . . . . 356

Implementing a Custom View Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358

A View Engine That Renders XML Using XSLT . . . . . . . . . . . . . . . . . 358

■CONTENTS xiii

Page 12: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Using Alternative View Engines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363

Using the NVelocity View Engine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363

Using the Brail View Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365

Using the Spark View Engine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366

Using the NHaml View Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368

■CHAPTER 11 Data Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369

Model Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369

Model-Binding to Action Method Parameters . . . . . . . . . . . . . . . . . . 370

Model-Binding to Custom Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371

Invoking Model Binding Directly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374

Model-Binding to Arrays, Collections, and Dictionaries . . . . . . . . . 376

Creating a Custom Model Binder . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378

Using Model Binding to Receive File Uploads . . . . . . . . . . . . . . . . . . 381

Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383

Registering Errors in ModelState. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383

View Helpers for Displaying Error Information . . . . . . . . . . . . . . . . . 386

How the Framework Maintains State in Input Controls. . . . . . . . . . 388

Performing Validation During Model Binding . . . . . . . . . . . . . . . . . . 389

Moving Validation Logic into Your Model Layer . . . . . . . . . . . . . . . . 390

About Client-Side (JavaScript) Validation . . . . . . . . . . . . . . . . . . . . . 395

Wizards and Multistep Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396

Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406

Implementing a CAPTCHA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406

Confirmation Links and Tamper-Proofing with HMAC Codes. . . . . 414

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418

■CHAPTER 12 Ajax and Client Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419

Why You Should Use a JavaScript Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . 419

ASP.NET MVC’s Ajax Helpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420

Fetching Page Content Asynchronously Using Ajax.ActionLink . . . 421

Submitting Forms Asynchronously Using Ajax.BeginForm . . . . . . . 427

Invoking JavaScript Commands from an Action Method . . . . . . . . 428

Reviewing ASP.NET MVC’s Ajax Helpers . . . . . . . . . . . . . . . . . . . . . . 430

Using jQuery with ASP.NET MVC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431

Referencing jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431

Basic jQuery Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433

Adding Client-Side Interactivity to an MVC View . . . . . . . . . . . . . . . 438

Ajax-Enabling Links and Forms. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442

■CONTENTSxiv

Page 13: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Client/Server Data Transfer with JSON . . . . . . . . . . . . . . . . . . . . . . . 449

Fetching XML Data Using jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452

Animations and Other Graphical Effects . . . . . . . . . . . . . . . . . . . . . . 453

jQuery UI’s Prebuilt User Interface Widgets. . . . . . . . . . . . . . . . . . . . 454

Implementing Client-Side Validation with jQuery . . . . . . . . . . . . . . . 456

Summarizing jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458

■CHAPTER 13 Security and Vulnerability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459

All Input Can Be Forged . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459

Forging HTTP Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461

Cross-Site Scripting and HTML Injection. . . . . . . . . . . . . . . . . . . . . . . . . . . 463

Example XSS Vulnerability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464

ASP.NET’s Request Validation Feature. . . . . . . . . . . . . . . . . . . . . . . . 465

Filtering HTML Using the HTML Agility Pack. . . . . . . . . . . . . . . . . . . 467

Session Hijacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468

Defense via Client IP Address Checks . . . . . . . . . . . . . . . . . . . . . . . . 469

Defense by Setting the HttpOnly Flag on Cookies . . . . . . . . . . . . . . 469

Cross-Site Request Forgery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470

Attack. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471

Defense . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471

Preventing CSRF Using the Anti-Forgery Helpers. . . . . . . . . . . . . . . 472

SQL Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473

Attack. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474

Defense by Encoding Inputs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474

Defense Using Parameterized Queries. . . . . . . . . . . . . . . . . . . . . . . . 474

Defense Using Object-Relational Mapping . . . . . . . . . . . . . . . . . . . . 475

Using the MVC Framework Securely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475

Don’t Expose Action Methods Accidentally . . . . . . . . . . . . . . . . . . . . 475

Don’t Allow Model Binding to Change Sensitive Properties . . . . . . 476

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476

■CHAPTER 14 Deployment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477

Server Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477

Requirements for Shared Hosting . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478

IIS Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478

Understanding Web Sites and Virtual Directories. . . . . . . . . . . . . . . 478

Binding Web Sites to Hostnames, IP Addresses, and Ports . . . . . . 480

How IIS Handles Requests and Invokes ASP.NET . . . . . . . . . . . . . . . 480

■CONTENTS xv

Page 14: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Deploying Your Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483

Copying Your Application Files to the Server . . . . . . . . . . . . . . . . . . 484

Using Visual Studio 2008’s Publish Feature . . . . . . . . . . . . . . . . . . . 485

Making It Work on Windows Server 2003/IIS 6 . . . . . . . . . . . . . . . . 486

Making It Work on IIS 7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494

Making Your Application Behave Well in Production. . . . . . . . . . . . . . . . . 497

Supporting Changeable Routing Configurations. . . . . . . . . . . . . . . . 497

Supporting Virtual Directories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498

Using ASP.NET’s Configuration Facilities. . . . . . . . . . . . . . . . . . . . . . 498

Controlling Compilation on the Server . . . . . . . . . . . . . . . . . . . . . . . . 502

Detecting Compiler Errors in Views Before Deployment . . . . . . . . . 503

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503

■CHAPTER 15 ASP.NET Platform Features. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505

Windows Authentication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506

Preventing or Limiting Anonymous Access . . . . . . . . . . . . . . . . . . . . 508

Forms Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509

Setting Up Forms Authentication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510

Using Cookieless Forms Authentication. . . . . . . . . . . . . . . . . . . . . . . 513

Membership, Roles, and Profiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514

Setting Up a Membership Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . 516

Using a Membership Provider with Forms Authentication . . . . . . . 520

Creating a Custom Membership Provider . . . . . . . . . . . . . . . . . . . . . 521

Setting Up and Using Roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522

Setting Up and Using Profiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525

URL-Based Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529

Data Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530

Reading and Writing Cache Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530

Using Advanced Cache Features. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533

Site Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534

Setting Up and Using Site Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535

Creating a Custom Navigation Control with the Site Maps API . . . . . 536

Generating Site Map URLs from Routing Data . . . . . . . . . . . . . . . . . 538

Internationalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540

Setting Up Internationalization. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541

Tips for Working with Resource Files. . . . . . . . . . . . . . . . . . . . . . . . . 544

Using Placeholders in Resource Strings . . . . . . . . . . . . . . . . . . . . . . 545

Performance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546

HTTP Compression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546

Tracing and Monitoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548

■CONTENTSxvi

Page 15: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Monitoring Page Generation Times. . . . . . . . . . . . . . . . . . . . . . . . . . . 549

Monitoring LINQ to SQL Database Queries . . . . . . . . . . . . . . . . . . . . 550

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554

■CHAPTER 16 Combining MVC and WebForms. . . . . . . . . . . . . . . . . . . . . . . . . . . 555

Using WebForms Technologies in an MVC Application. . . . . . . . . . . . . . . 555

Using WebForms Controls in MVC Views. . . . . . . . . . . . . . . . . . . . . . 556

Using WebForms Pages in an MVC Web Application. . . . . . . . . . . . 558

Adding Routing Support for WebForms Pages . . . . . . . . . . . . . . . . . 559

Using ASP.NET MVC in a WebForms Application . . . . . . . . . . . . . . . . . . . . 563

Upgrading an ASP.NET WebForms Application to Support MVC. . . . 564

Getting Visual Studio to Offer MVC Items . . . . . . . . . . . . . . . . . . . . . 568

Interactions Between WebForms Pages and MVC Controllers . . . . 569

Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571

■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573

■CONTENTS xvii

Page 16: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

xviii

About the Author

■STEVEN SANDERSON first learned to program computers by copyingBASIC listings from a Commodore VIC-20 instruction manual. That wasalso how he first learned to read.

Steve was born in Sheffield, UK, got his education by studying math-ematics at Cambridge, and now lives in Bristol. He worked for a giantinvestment bank, a tiny start-up company, and then a medium-sized ISVbefore going independent as a freelance web developer, consultant, andtrainer. Steve enjoys the UK’s .NET community and tries to participate in

user groups and speak at free conferences whenever he has the chance.Steve loves all forms of technological progress and will buy any gadget if it has flashing LEDs.

Page 17: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

xix

About the Technical Reviewer

■ANDY OLSEN is a freelance developer and consultant based in the United Kingdom. Andy hasbeen working with .NET since the beta 1 days and has coauthored and reviewed several booksfor Apress, covering C#, Visual Basic, ASP.NET, and other topics. Andy is a keen football andrugby fan and enjoys running and skiing (badly). Andy lives by the seaside in Swansea with hiswife, Jayne, and children, Emily and Thomas, who have just discovered the thrills of surfingand look much cooler than he ever will!

Page 18: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

xx

Acknowledgments

Getting this book published was a real team effort. I’ve been greatly impressed by the wholeApress crew: Sofia did a fantastic job of keeping the whole project on course, patiently replot-ting the schedule every time it had to change. Damon herded every comma and caption intoits right place, and tactfully removed many of my British expressions that would have baffledmost readers. Laura cheerfully accepted an endless stream of last-minute edits to the beauti-fully typeset PDFs. Ewan advocated the project from the start. My technical reviewer, Andy,had great insight into how much detail was needed in each explanation, and was relentlesslythorough in verifying the correctness of my work. Needless to say, any technical errors in thisbook will be the ones that I secretly inserted after Andy had completed his reviews.

Many readers have already provided feedback on early drafts of this book publishedthrough Apress’s Alpha Program. You all deserve credit, because you’ve helped to improve thequality and consistency of explanations and terminology used throughout.

We all owe thanks to certain Microsoft staff, not just for giving us an excellent new webdevelopment framework, but also for the way they did it. Phil Haack, Scott Guthrie, and theirfrighteningly smart team continually responded to customer feedback during the develop-ment process, bravely putting their work-in-progress on show every two months, no matterwhat criticisms they had to field. They challenged our view of Microsoft by releasing the wholeframework’s source code on http://codeplex.com/, and dramatically supported the opensource community by shipping jQuery as a supported, endorsed add-on.

The final credit goes to Zoe, my wife, who took on the practical burdens of both ourlives so that I could always keep writing. I’m pretty sure she put more work into this projectthan I did.

Page 19: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

xxi

Introduction

We’ve waited a long time for this! The first rough early preview release of ASP.NET MVC wasmade public in December 2007, and immediately the software development world was filledwith eager enthusiasm for it. Could this be the most exciting advancement in Microsoft webtechnology since ASP.NET itself was born way back in 2002? Would we, at last, have a webdevelopment framework that encourages and supports high-quality software engineering?

Since then, we’ve had five further community technology preview (CTP) releases, onebeta release, two release candidates, and now at last in March 2009, the finished 1.0 release.Some releases were just incremental improvements on their predecessors; others were sub-stantial shifts in the framework’s mechanics and aesthetics (e.g., the whole notion of modelbinding, covered in Chapter 11, didn’t appear until preview 5). At each stage, the ASP.NET MVCteam invited feedback and guided their development efforts according to real-world usageexperiences. Not all Microsoft products are built this way; consequently, ASP.NET MVC 1.0 ismuch more mature than the average 1.0 release.

I started work on this book in December 2007, foolishly anticipating a summer 2008 pub-lication date. With every new preview release, the whole manuscript was updated, reworked,expanded, polished even more—sometimes even whole chapters became obsolete and simplyhad to be discarded. The project became so ingrained into my life that every conversationwith friends, family, or colleagues began by them asking “How’s the book?” shortly followed by,“Tell me again—what’s the book about?” I hope that this finished manuscript, created in par-allel with ASP.NET MVC itself, gives you not just a clear understanding of what the frameworkdoes today, but also why it was designed this way and how the same principles can improvethe quality of your own code.

Who This Book Is ForThis book is for professional software developers who already have a working understanding ofC# and general web development concepts such as HTML and HTTP. Ideally, you’ll have usedtraditional ASP.NET (which these days is known as WebForms, to distinguish it from MVC), butif you’ve used PHP, Rails, or another web development platform, then that’s fine too.

All of the code samples in this book are written in C#. That’s not because Visual Basic or any other .NET language is inadequate, but simply because C# is by far the most popularchoice among ASP.NET MVC programmers. Don’t worry if you haven’t used LINQ or .NET 3.5yet—the relevant new C# 3 syntaxes are covered briefly at the end of Chapter 3. However, ifyou’re totally new to C#, you might also like to pick up a copy of Pro C# 2008 and the .NET 3.5Platform, Fourth Edition, by Andrew Troelsen (Apress, 2007).

Finally, I will assume that you have a reasonable level of passion for your craft. I hopeyou’re not satisfied just to throw together any old code that appears at first to work, butinstead would prefer to hone your skills by learning the design patterns, goals, and principles

Page 20: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

underpinning ASP.NET MVC. This book frequently compares your architectural options,aspiring to help you create the highest-quality, most robust, simple, and maintainable codepossible.

How This Book Is StructuredThis book comes in two parts:

• Chapters 1 through 6 are intended to get you up to speed with the big ideas in ASP.NETMVC and its relationship with modern web application architecture and testing. Four ofthese chapters are hands-on tutorials grounding those ideas in real application build-ing. These six chapters should be read sequentially.

• Chapters 7 through 16 then dig deep into each major technology area in the MVCFramework, exploring how you can get maximum benefit from almost every frameworkfeature. The last few chapters describe important ancillary topics such as security,deployment, and integrating with or migrating from legacy WebForms code. These tenchapters should make sense whether you read them sequentially or dip in and out asneeded.

Sample CodeYou can download completed versions of each of the major tutorial applications in this book,plus many of the more complex code samples shown in other chapters.

To obtain these files, visit the Apress web site at www.apress.com/, and search for thisbook. You can then download the sample code, which is compressed into a single ZIP file.Code is arranged into separate directories by chapter. Before using the code, refer to theaccompanying readme.txt file for information about other prerequisites and considerations.

ErrataThe author, the technical reviewer, and numerous Apress staff have made every effort todetect and eliminate all errors from this book’s text and code. However, I’m sure there will stillbe one or two glitches in here somewhere! To keep you informed, there’s an errata sheet on thebook’s page on www.apress.com/. If you find any errors that haven’t already been reported,such as misspellings or faulty code, please let us know by e-mailing [email protected].

Customer SupportApress always values hearing from its readers, and wants to know what you think about thisbook—what you liked, what you didn’t like, and what you think could be done better nexttime. You can send your comments by e-mail to [email protected]. Please be sure to men-tion the book title in your message.

xxii ■INTRODUCTION

Page 21: Pro ASP.NET MVC Framework - Home - Springer978-1-4302-1008-5/1 · Pro ASP.NET MVC Framework ... Using LINQ to SQL ... A View Engine That Renders XML Using XSLT.....358 CONTENTS xiii

Contacting the AuthorYou can e-mail me at [email protected], or contact me through my blog athttp://blog.stevensanderson.com. I’ll do my best to reply even if sometimes there’s a bit of a delay before I can do so!

If you’re looking for general ASP.NET MVC support, then instead please use the product’sonline forum, at http://forums.asp.net/1146.aspx.

xxiii■INTRODUCTION