Tải bản đầy đủ (.pdf) (516 trang)

programming microsoft asp net mvc 3rd edition feb 2014

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (10.95 MB, 516 trang )

Programming Microsoft
ASP.NET MVC, Third
Edition
Dino Esposito
Published with the authorization of Microsoft Corporation by:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, California 95472
Copyright © 2014 Leonardo Esposito
All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form or by any
means without the written permission of the publisher.
ISBN: 978-0-7356-8094-4
1 2 3 4 5 6 7 8 9 LSI 9 8 7 6 5 4
Printed and bound in the United States of America.
Microsoft Press books are available through booksellers and distributors worldwide. If you need support related
to this book, email Microsoft Press Book Support at Please tell us what you think of
this book at
Microsoft and the trademarks listed at />Trademarks/EN-US.aspx are trademarks of the Microsoft group of companies. All other marks are property of
their respective owners.
The example companies, organizations, products, domain names, email addresses, logos, people, places, and
events depicted herein are ctitious. No association with any real company, organization, product, domain name,
email address, logo, person, place, or event is intended or should be inferred.
This book expresses the author’s views and opinions. The information contained in this book is provided without
any express, statutory, or implied warranties. Neither the author, O’Reilly Media, Inc., Microsoft Corporation, nor
its resellers, or distributors will be held liable for any damages caused or alleged to be caused either directly or
indirectly by this book.
Acquisitions and Developmental Editors: Russell Jones and Rachel Roumeliotis
Production Editor: Kristen Brown
Editorial Production: Dianne Russell, Octal Publishing, Inc.


Technical Reviewer: John Mueller
Copyeditor: Bob Russell, Octal Publishing, Inc.
Indexer: BIM Indexing Services
Cover Design: Twist Creative • Seattle and Joel Panchot
Cover Composition: Ellie Volckhausen
Illustrator: Rebecca Demarest
To Silvia, Francesco, Michela, and my back for sustaining me.
—Dino

Contents at a glance
Introduction xiii
PART I ASP.NET MVC FUNDAMENTALS
CHAPTER 1 ASP.NET MVC controllers 3
CHAPTER 2 ASP.NET MVC views 33
CHAPTER 3 The model-binding architecture 75
CHAPTER 4 Input forms 103
PART II ASP.NET MVC SOFTWARE DESIGN
CHAPTER 5 Aspects of ASP.NET MVC applications 151
CHAPTER 6 Securing your application 189
CHAPTER 7 Design considerations for ASP.NET MVC controllers 225
CHAPTER 8 Customizing ASP.NET MVC controllers 255
CHAPTER 9 Testing and testability in ASP.NET MVC 301
CHAPTER 10 An executive guide to Web API 337
PART III MOBILE CLIENTS
CHAPTER 11 Effective JavaScript 367
CHAPTER 12 Making websites mobile-friendly 399
CHAPTER 13 Building sites for multiple devices 439
Index 469

vii

Contents
Introduction xiii
PART I ASP.NET MVC FUNDAMENTALS
Chapter 1 ASP.NET MVC controllers 3
Routing incoming requests 4
Simulating the ASP.NET MVC runtime 4
The URL routing HTTP module 7
Application routes 9
The controller class 15
Aspects of a controller 16
Writing controller classes 17
Processing input data 22
Producing action results 25
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30
Chapter 2 ASP.NET MVC views 33
The structure and behavior of a view engine 34
The mechanics of a view engine 34
Denition of the view template 39
HTML helpers 42
Basic helpers 43
Templated helpers 48
Custom helpers 51
The Razor view engine 54
Inside the view engine 54
Designing a sample view 59
Coding the view 65
Modeling the view 65
Advanced features 70
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
viii Contents

Chapter 3 The model-binding architecture 75
The input model 76
Evolving from the Web Forms input processing 76
Input processing in ASP.NET MVC. . . . . . . . . . . . . . . . . . . . . . . . . . . . .78
Model binding 79
Model-binding infrastructure 79
The default model binder 80
Customizable aspects of the default binder 91
Advanced model binding 93
Custom type binders 93
A sample DateTime model binder 96
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
Chapter 4 Input forms 103
General patterns of data entry 104
A classic Select-Edit-Post scenario 104
Applying the Post-Redirect-Get pattern 112
Automating the writing of input forms 117
Predened display and editor templates 117
Custom templates for model data types 125
Input validation 130
Using data annotations 130
Advanced data annotations 135
Self-validation 142
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .146
PART II ASP.NET MVC SOFTWARE DESIGN
Chapter 5 Aspects of ASP.NET MVC applications 151
ASP.NET intrinsic objects 151
HTTP response and SEO 152
Managing the session state 155
Caching data 157

ix
Error handling 163
Handling program exceptions 163
Global error handling 169
Dealing with missing content 172
Localization 175
Using localizable resources 175
Dealing with localizable applications 182
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .187
Chapter 6 Securing your application 189
Security in ASP.NET MVC 189
Authentication and authorization 190
Separating authentication from authorization 192
Implementing a membership system 195
Dening a membership controller 196
The Remember-Me feature and Ajax 204
External authentication services 207
The OpenID protocol 208
Authenticating via social networks 215
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .223
Chapter 7 Design considerations for ASP.NET MVC controllers 225
Shaping up your controller 226
Choosing the right stereotype 226
Fat-free controllers 230
Connecting the presentation and back end. . . . . . . . . . . . . . . . . . . . . . . . .237
The Layered Architecture pattern 237
Injecting data and services in layers 244
Gaining control of the controller factory 250
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253
x Contents

Chapter 8 Customizing ASP.NET MVC controllers 255
The extensibility model of ASP.NET MVC 255
The provider-based model 256
The Service Locator pattern 259
Adding aspects to controllers 263
Action lters 263
Gallery of action lters 267
Special lters 274
Building a dynamic loader lter 279
Action result types 285
Built-in action result types 285
Custom result types 290
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .299
Chapter 9 Testing and testability in ASP.NET MVC 301
Testability and design. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .302
DfT 302
Loosen up your design 304
The basics of unit testing 308
Working with a test harness 309
Aspects of testing 313
Testing your ASP.NET MVC code 319
Which part of your code should you test? 319
Unit testing ASP.NET MVC code 322
Dealing with dependencies 326
Mocking the HTTP context 328
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .335
Chapter 10 An executive guide to Web API 337
The whys and wherefores of Web API 337
The need for a unied HTTP API 338
MVC controllers vs. Web API 339

Contents xi
Putting Web API to work 341
Designing a RESTful interface 342
Expected method behavior 346
Using the Web API 348
Designing an RPC-oriented Interface 352
Security considerations 355
Negotiating the response format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .359
The ASP.NET MVC approach 359
How content negotiation works in Web API 360
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
PART III MOBILE CLIENTS
Chapter 11 Effective JavaScript 367
Revisiting the JavaScript language 368
Language basics 368
Object-orientation in JavaScript 373
jQuery’s executive summary 377
DOM queries and wrapped sets 377
Selectors 379
Events 384
Aspects of JavaScript programming 387
Unobtrusive code 387
Reusable packages and dependencies 388
Script and resource loading 391
Bundling and minication 394
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .397
Chapter 12 Making websites mobile-friendly 399
Technologies for enabling mobile on sites 399
HTML5 for the busy developer 400
RWD 407

jQuery Mobile’s executive summary 413
Twitter Bootstrap at a glance 423
xii Contents
Adding mobile capabilities to an existing site 430
Routing users to the correct site 431
From mobile to devices 436
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .437
Chapter 13 Building sites for multiple devices 439
Understanding display modes in ASP.NET MVC 440
Separated mobile and desktop views 440
Rules for selecting the display mode 442
Adding custom display modes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .443
Introducing the WURFL database 446
Structure of the repository 447
Essential WURFL capabilities 451
Using WURFL with ASP.NET MVC display modes 454
Conguring the WURFL framework 454
Detecting device capabilities 456
Using WURFL-based display modes 459
The WURFL cloud API 464
Why you should consider server-side solutions 466
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .467
Index 469
About the author 495
What do you think of this book? We want to hear from you!
Microsoft is interested in hearing your feedback so we can continually improve our
books and learning resources for you. To participate in a brief online survey, please visit:
microsoft.com/learning/booksurvey
xiii
Introduction

Get your facts rst, and then you can distort them as much as you
please.
—Mark Twain
A
SP.NET was devised in the late 1990s at a time when many companies in various
industry sectors were rapidly discovering the Internet. The primary goal of ASP.NET
was to make it possible for developers to build applications quickly and effectively with-
out having to deal with low-level details such as HTTP, HTML, and JavaScript intricacies.
That was exactly what the community loudly demanded at that time. ASP.NET is what
Microsoft delivered to address this request, exceeding expectations by a large extent.
Today, more than ten years later, ASP.NET is showing signs of age, and many started
even questioning the real necessity of having a web framework at all. It’s an amazing
time, and several options exist. There are Web Forms and ASP.NET MVC applications,
and then there are more JavaScript-intensive client applications (single-page applica-
tions) that just use a server-side back end for delivering the basic layout of the few
pages they actually expose and for ad hoc services such as bundling.
Curiously, with the Web Forms paradigm, you can still write functional applications
even though ASP.NET MVC addresses more closely the present needs of developers.
The most common scenario of Web Forms is applications for which you focus on
presenting data and use some third-party high-quality suite of controls for that. ASP.NET
MVC is for everything else, including the scaffolding of client-side single-page applications.
The way web applications are changing proves that ASP.NET MVC probably failed to
replace ASP.NET Web Forms in the heart of many developers, but it was the right choice
and qualies to be the ideal web platform for any application that needs a back end of
some substance; in particular (as I see things), web applications that aim at being multi-
device functional. And yes, that likely means all web applications in less than two years.
Switching to ASP.NET MVC is more than ever the natural follow-up for ASP.NET
developers.
xiv Introduction
Who should read this book

Over the years, quite a few people have read quite a few books and articles of mine.
These readers are already aware that I’m not good at writing step-by-step, reference-
style books, in the similar manner that I'm unable to teach the same class twice, running
topics in the same order and showing the same examples.
This book is not for absolute beginners; but I do feel it is a book for all the oth-
ers, including those who are still fairly new to ASP.NET MVC. The higher your level of
competency and expertise, the less you can expect to nd here that adds value in your
particular case. However, this book benets from a few years of real-world practice; so
I’m sure it has a lot of solutions that might also appeal to the experts, particularly with
respect to mobile devices.
If you use ASP.NET MVC, I’m condent that you’ll nd something in this book that
makes it worthwhile.
Assumptions
This book expects that you have at least a minimal understanding of ASP.NET development.
Who should not read this book
If you’re looking for a step-by-step guide to ASP.NET MVC, this is not the ideal book
for you.
Organization of this book
This book is divided into three sections. Part I, “ASP.NET MVC fundamentals,” provides a
quick overview of the foundation of ASP.NET and its core components. Part II, “ASP.NET
MVC software design,” focuses on common aspects of web applications and specic
design patterns and best practices. Finally, Part III, “Mobile clients,” is about JavaScript
and mobile interfaces.
Introduction xv
System requirements
You preferably have the following software installed in order to run the examples pre-
sented in this book:

One of the following operating systems: Windows 8/8.1, Windows 7, Windows
Vista with Service Pack 2 (except Starter Edition), Windows XP with Service Pack

3 (except Starter Edition), Windows Server 2008 with Service Pack 2, Windows
Server 2003 with Service Pack 2, or Windows Server 2003 R2

Microsoft Visual Studio 2013, any edition (multiple downloads might be re-
quired if you’re using Express Edition products)

Microsoft SQL Server 2012 Express Edition or higher, with SQL Server Manage-
ment Studio 2012 Express or higher (included with Visual Studio; Express Edi-
tions require a separate download)
Depending on your Windows conguration, you might require Local Administrator
rights to install or congure Visual Studio 2013 and SQL Server 2012 products.
Code samples
Most of the chapters in this book include exercises with which you can interactively try
out new material learned in the main text. You can download all sample projects, in
both their pre-exercise and post-exercise formats, from the following page:
/>Follow the instructions to download the asp-net-mvc-examples.zip le.
Installing the code samples
Perform the following steps to install the code samples on your computer so that you
can use them with the exercises in this book.
1. Unzip the asp-net-mvc-examples.zip le that you downloaded from the book’s
website (name a specic directory along with directions to create it, if necessary).
2. If prompted, review the displayed end-user license agreement. If you accept the
terms, select the Accept option, and then click Next.
Note If the license agreement doesn’t appear, you can access it from the
same webpage from which you downloaded the
asp-net-mvc-examples.zip le.
Using the code samples
The folder created by the Setup.exe program contains one subfolder for each chapter.
In turn, each chapter might contain additional subfolders. All examples are organized in
a single Visual Studio 2013 solution. You open the solution le in Visual Studio 2013 and

navigate through the examples.
Errata & book support
We’ve made every effort to ensure the accuracy of this book and its companion con-
tent. Any errors that have been reported since this book was published are listed on our
Microsoft Press site:
/>If you nd an error that is not already listed, you can report it to us through the
same page.
If you need additional support, email Microsoft Press Book Support at mspinput@
microsoft.com.
Please note that product support for Microsoft software is not offered through the
aforementioned addresses.
We want to hear from you
At Microsoft Press, your satisfaction is our top priority, and your feedback our most
valuable asset. Please tell us what you think of this book at:
/>The survey is short, and we read every one of your comments and ideas. Thanks in
advance for your input!
Introduction xvii
Stay in touch
Let’s keep the conversation going! We’re on Twitter: />
1
PART I
ASP.NET MVC
fundamentals
CHAPTER 1 ASP.NET MVC controllers 3
CHAPTER 2 ASP.NET MVC views 33
CHAPTER 3 The model-binding architecture 75
CHAPTER 4 Input forms 103
3
CHAPTER 1

ASP.NET MVC controllers
They always say time changes things, but you actually have to change them yourself.
—Andy Warhol
I
think ASP.NET Web Forms started getting old the day that Ajax conquered the masses. As some have
said, Ajax has been the poisonous arrow shot in the heel of ASP.NET—another Achilles. Ajax made
getting more and more control over HTML and client-side code a true necessity. Over time, this led to
different architectures and made ASP.NET Web Forms a little less up to the task with each passing day.
Applied to the existing ASP.NET runtime, the MVC pattern produced a new framework—ASP.NET
MVC—that aligns web development to the needs of developers today.
In ASP.NET MVC, each request results in the execution of an action—ultimately, a method on a
specic class. The results of executing the action are passed down to the view subsystem along with a
view template. The results and template are then used to build the nal response for the browser. Us-
ers don’t point the browser to a page, they just place a request. Doesn’t that sound like a big change?
Unlike Web Forms, ASP.NET MVC is made of various layers of code connected together but not
intertwined and not forming a single monolithic block. For this reason, it’s easy to replace any of
these layers with custom components that enhance the maintainability as well as the testability of the
solution. With ASP.NET MVC, you gain total control over the markup and can apply styles and inject
script code at will using the JavaScript frameworks that you like most.
Based on the same run-time environment as Web Forms, ASP.NET MVC pushes a web-adapted
implementation of the classic Model-View-Controller pattern and makes developing web applications
a signicantly different experience. In this chapter, you’ll discover the role and structure of the con-
troller—the foundation of ASP.NET MVC applications—and how requests are routed to controllers.
Although you might decide to keep using Web Forms, for today’s web development, ASP.NET MVC
is a much better choice. You don’t need to invest a huge amount of time, but you need to understand
exactly what’s going on and the philosophy behind MVC. If you do that, any investment you make will
pay you back sooner than you expect.
4 PART I ASP.NET MVC fundamentals
Note This book is based on ASP.NET MVC 5. This version of ASP.NET MVC is backward
compatible with the previous versions. This means that you can install both versions side

by side on the same computer and play with the new version without affecting any existing
MVC code that you might have already.
Routing incoming requests
Originally, the entire ASP.NET platform was developed around the idea of serving requests for physi-
cal pages. It turns out that most URLs used within an ASP.NET application are made of two parts: the
path to the physical webpage that contains the logic, and some data stuffed in the query string to
provide parameters. This approach has worked for a few years, and it still works today. The ASP.NET
run-time environment, however, doesn’t limit you to just calling into resources identied by a specic
location and le. By writing an ad hoc HTTP handler and binding it to a URL, you can use ASP.NET to
execute code in response to a request regardless of the dependencies on physical les. This is just one
of the aspects that most distinguishes ASP.NET MVC from ASP.NET Web Forms. Let’s briey see how
to simulate the ASP.NET MVC behavior with an HTTP handler.
Note In software, the term URI (which stands for Uniform Resource Identier) is used to
refer to a resource by location or a name. When the URI identies the resource by location,
it’s called a URL, or Uniform Resource Locator. When the URI identies a resource by name,
it becomes a URN, or Uniform Resource Name. In this regard, ASP.NET MVC is designed
to deal with more generic URIs, whereas ASP.NET Web Forms was designed to deal with
location-aware physical resources.
Simulating the ASP.NET MVC runtime
Let’s build a simple ASP.NET Web Forms application and use HTTP handlers to gure out the internal
mechanics of ASP.NET MVC applications. You can start from the basic ASP.NET Web Forms application
you get from your Microsoft Visual Studio project manager.
Dening the syntax of recognized URLs
In a world in which requested URLs don’t necessarily match up with physical les on the web server, the
rst step to take is listing which URLs are meaningful for the application. To avoid being too specic,
let’s assume that you support only a few xed URLs, each mapped to an HTTP handler component. The
following code snippet shows the changes required to be made to the default web.cong le:
CHAPTER 1 ASP.NET MVC controllers 5
<httpHandlers>
<add verb="*"

path="home/test/*"
type="MvcEmule.Components.MvcEmuleHandler" />
</httpHandlers>
Whenever the application receives a request that matches the specied URL, it will pass it on to the
specied handler.
Dening the behavior of the HTTP handler
In ASP.NET, an HTTP handler is a component that implements the IHttpHandler interface. The inter-
face is simple and consists of two members, as shown here:
public class MvcEmuleHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// Logic goes here

}

public Boolean IsReusable
{
get { return false; }
}
}
Most of the time, an HTTP handler has a hardcoded behavior inuenced only by some input data
passed via the query string. However, nothing prevents us from using the handler as an abstract
factory for adding one more level of indirection. The handler, in fact, can use information from the
request to determine an external component to call to actually serve the request. In this way, a single
HTTP handler can serve a variety of requests and just dispatch the call among a few more specialized
components.
The HTTP handler could parse out the URL in tokens and use that information to identify the class
and the method to invoke. Here’s an example of how it could work:
public void ProcessRequest(HttpContext context)

{
// Parse out the URL and extract controller, action, and parameter
var segments = context.Request.Url.Segments;
var controller = segments[1].TrimEnd(‘/’);
var action = segments[2].TrimEnd(‘/’);
var param1 = segments[3].TrimEnd(‘/’);

// Complete controller class name with suffix and (default) namespace
var fullName = String.Format("{0}.{1}Controller",
this.GetType().Namespace, controller);
var controllerType = Type.GetType(fullName, true, true);

×