Professional ASP.NET MVC 5

MVC 5 and Creating Applications, Controllers, Views and Models in depth including advance features of MVC5

Jon, Brad Wilson, K. Scott Allen, David Matson

620 Pages

84354 Reads



PDF Format

8.15 MB

Other Books

Download PDF format

  • Jon, Brad Wilson, K. Scott Allen, David Matson   
  • 620 Pages   
  • 25 Feb 2015
  • Page - 1

    read more..

  • Page - 2

    read more..

  • Page - 3

    PROFESSIONAL ASP.NET MVC 5 FOREWORD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxvii INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix read more..

  • Page - 4

    read more..

  • Page - 5

    PROFESSIONAL ASP.NET MVC 5 read more..

  • Page - 6

    read more..

  • Page - 7

    PROFESSIONAL ASP.NET MVC 5 Jon Galloway Brad Wilson K. Scott Allen David Matson read more..

  • Page - 8

    Professional ASP.NET MVC 5 Published by John Wiley & So ns, Inc. 10475 Crosspoint Boulevard Indianapolis, IN 46256 Copyright © 2 014 by John Wiley & So ns, Inc., Indianapolis, Indiana Published by John Wiley & So ns, Inc., Indianapolis, Indiana Published simultaneously in Canada ISBN: 978-1-118-79475-3 ISBN: 978-1-118-79472-2 (ebk) ISBN: 978-1-118-79476-0 (ebk) read more..

  • Page - 9

    To my wife, Rachel, my daughters, Rosemary, Esther, and Ellie, and to you reading this book. Enjoy! — Jon Galloway To Potten on Potomac. — K. Scott Allen read more..

  • Page - 10

    read more..

  • Page - 11

    ABOUT THE AUTHORS JON GALLOWAY works at Microsoft as a Technical Evangelist focused on ASP.NET and Azure. He writes samples and tutorials like the MVC Music Store and is a frequent speaker at web conferences and international Web Camps events. Jon’s been doing professional web development since 1998, including high scale applications in fi nancial, read more..

  • Page - 12

    read more..

  • Page - 13

    ABOUT THE TECHNICAL EDITORS EILON LIPTON joined the ASP.NET team as a developer at Microsoft in 2002. On this team, he has worked on areas ranging from data source controls to localization to the UpdatePanel control. He is now a development manager on the ASP.NET team working on open source projects including ASP. NET MVC, Web API, Web Pages read more..

  • Page - 14

    read more..

  • Page - 15


  • Page - 16

    read more..

  • Page - 17

    ACKNOWLEDGMENTS THANKS TO FAMILY AND FRIENDS who graciously acted as if “Jon without sleep” is someone you’d want to spend time with. Thanks to the whole ASP.NET team for making work fun since 2002. Thanks to Warren G. Harding for normalcy. Thanks to Philippians 4:4–9 for continually reminding me which way is up. — Jon Galloway read more..

  • Page - 18

    read more..

  • Page - 19

    CONTENTS FOREWORD xxvii INTRODUCTION xxix CHAPTER 1: GETTING STARTED 1 A Quick Introduction to ASP.NET MVC 1 How ASP.NET MVC Fits in with ASP.NET 2 The MVC Pattern 2 MVC as Applied to Web Frameworks 3 The Road to MVC 5 3 MVC 4 Overview 6 Open-Source Release 10 ASP.NET MVC 5 Overview 11 One ASP.NET 11 New Web Project Experience 12 ASP.NET Identity 12 read more..

  • Page - 20

    xviii CONTENTS Controller Basics 38 A Simple Example: The Home Controller 39 Writing Your First Controller 42 Parameters in Controller Actions 45 Summary 47 CHAPTER 3: VIEWS 49 The Purpose of Views 50 View Basics 50 Understanding View Conventions 54 Strongly Typed Views 55 How ViewBag Falls Short 55 Understanding ViewBag, ViewData, and ViewDataDictionary 57 View read more..

  • Page - 21

    xix CONTENTS CHAPTER 5: FORMS AND HTML HELPERS 109 Using Forms 110 The Action and the Method 110 To GET or to POST? 111 HTML Helpers 114 Automatic Encoding 115 Making Helpers Do Your Bidding 115 Inside HTML Helpers 116 Setting Up the Album Edit Form 117 Adding Inputs 118 Helpers, Models, and View Data 124 Strongly Typed Helpers 126 Helpers and read more..

  • Page - 22

    xx CONTENTS ReadOnly 157 DataType 157 UIHint 158 HiddenInput 158 Summary 158 CHAPTER 7: MEMBERSHIP, AUTHORIZATION, AND SECURITY 159 Security: Not fun, But Incredibly Important 159 Using the Authorize Attribute to Require Login 162 Securing Controller Actions 162 How AuthorizeAttribute Works with Forms Authentication and the AccountController 167 Windows Authentication 169 Using read more..

  • Page - 23

    xxi CONTENTS Ajax Helpers 225 Adding the Unobtrusive Ajax Script to Your Project 225 Ajax ActionLinks 226 HTML 5 Attributes 230 Ajax Forms 230 Client Validation 233 jQuery Validation 233 Custom Validation 236 Beyond Helpers 241 jQuery UI 242 Autocomplete with jQuery UI 243 JSON and Client-Side Templates 246 Bootstrap Plugins 251 Improving Ajax Performance read more..

  • Page - 24

    xxii CONTENTS Custom Route Constraints 295 Using Routing with Web Forms 296 Summary 297 CHAPTER 10: NUGET 299 Introduction to NuGet 299 Adding a Library as a Package 301 Finding Packages 301 Installing a Package 303 Updating a Package 308 Package Restore 308 Using the Package Manager Console 309 Creating Packages 312 Packaging a Project 313 Packaging a Folder 313 read more..

  • Page - 25

    xxiii CONTENTS Adding Routes to Your Web API 346 Binding Parameters 347 Filtering Requests 349 Enabling Dependency Injection 350 Exploring APIs Programmatically 350 Tracing the Application 352 Web API Example: ProductsController 352 Summary 354 CHAPTER 12: SINGLE PAGE APPLICATIONS WITH ANGULARJS 355 Understanding and Setting Up AngularJS 356 What’s AngularJS? 356 Your Goal read more..

  • Page - 26

    xxiv CONTENTS Arbitrary Objects in Web API 405 Dependency Resolvers in MVC vs. Web API 405 Summary 405 CHAPTER 14: UNIT TESTING 407 Understanding Unit Testing and Test-Driven Development 408 Defi ning Unit Testing 408 Defi ning Test-Driven Development 410 Building a Unit Test Project 412 Examining the Default Unit Tests 413 Test Only the Code You Write 415 read more..

  • Page - 27

    xxv CONTENTS Advanced View Engines 476 Confi guring a View Engine 477 Finding a View 478 The View Itself 479 Alternative View Engines 480 New View Engine or New ActionResult? 482 Advanced Scaffolding 482 Introducing ASP.NET Scaffolding 482 Customizing Scaffold Templates 483 Custom Scaffolders 485 Advanced Routing 486 RouteMagic 486 Editable Routes 487 Advanced read more..

  • Page - 28

    xxvi CONTENTS AnglicanGeek.MarkdownMailer 543 Ninject 543 Summary 544 APPENDIX: ASP.NET MVC 5.1 545 ASP.NET MVC 5.1 Release Description 545 Getting MVC 5.1 546 Upgrading MVC 5 Projects from MVC 5.1 546 Upgrading an MVC 5 Application to 5.1 547 Enum Support in ASP.NET MVC Views 549 Attribute Routing with Custom Constraints 553 Route Constraints in Attribute Routing 554 ASP.NET read more..

  • Page - 29

    FOREWORD I’m thrilled to introduce this book covering the latest release of ASP.NET MVC, written by an outstanding team of authors. They are my friends, but more importantly, they are fantastic technologists. Jon Galloway is a Technical Evangelist at Microsoft focused on Azure and ASP.NET. In that role, he’s had the opportunity to work with read more..

  • Page - 30

    like something, use it; if you don’t like something, change it. You can unit test how you want, create components as you want, and use your choice of JavaScript framework. Perhaps the most exciting update in ASP.NET MVC 5 is the introduction of One ASP.NET. With this release, you can easily develop hybrid applications and share code read more..

  • Page - 31

    INTRODUCTION IT’S A GREAT TIME to be an ASP.NET developer! Whether you’ve been developing with ASP.NET for years or are just getting started, now is a great time to dig into ASP.NET MVC. ASP.NET MVC has been a lot of fun to work with from the start, but the last two releases have added many features that make the entire read more..

  • Page - 32

    xxx INTRODUCTION from the development team. Finally, there’s a new chapter from K. Scott Allen explaining how to build Single Page Applications with AngularJS. HOW THIS BOOK IS STRUCTURED This book is divided into two very broad sections, each comprising several chapters. The fi rst six chapters are concerned with introducing the MVC pattern and how ASP.NET MVC read more..

  • Page - 33

    xxxi INTRODUCTION ➤ Chapter 10, “NuGet,” introduces you to the NuGet package management system. You’ll learn how it relates to ASP.NET MVC, how to install it, and how to use it to install, update, and create new packages. ➤ Chapter 11, “ASP.NET Web API,” shows how to create HTTP services using the new ASP. NET Web API. ➤ Chapter 12, “Single Page Applications read more..

  • Page - 34

    xxxii INTRODUCTION You can also use ASP.NET MVC 5 with Visual Studio 2012. This is included as part of an update for ASP.NET and Web Tools for Visual Studio 2012 available at the following location: ➤ ASP.NET and Web Tools 2013.2 for Visual Studio 2012: en-us/download/41532 Chapter 1 reviews the software requirements in depth, read more..

  • Page - 35

    xxxiii INTRODUCTION NuGet is a package manager for .NET and Visual Studio written by the Outercurve Foundation and incorporated by Microsoft into ASP.NET MVC. Rather than having to search around for ZIP fi les on the Wrox website for source code samples, you can use NuGet to easily add these fi les into an ASP.NET MVC application from the convenience read more..

  • Page - 36

    xxxiv INTRODUCTION P2P.WROX.COM For author and peer discussion, join the P2P forums at . The forums are a web-based system for you to post messages relating to Wrox books and related technologies and interact with other readers and technology users. The forums offer a subscription feature to e-mail you topics of interest of your choosing when read more..

  • Page - 37

    Getting Started —by Jon Galloway WHAT’S IN THIS CHAPTER? ➤ Understanding ASP.NET MVC ➤ An overview of ASP.NET MVC 5 ➤ How to create MVC 5 applications ➤ How MVC applications are structured This chapter gives you a quick introduction to ASP.NET MVC, explains how ASP.NET MVC 5 fi ts into the ASP.NET MVC release history, summarizes what’s new read more..

  • Page - 38

    2 ❘ CHAPTER 1 GETTING STARTED How ASP.NET MVC Fits in with ASP.NET When ASP.NET 1.0 was fi rst released in 2002, it was easy to think of ASP.NET and Web Forms as one and the same thing. ASP.NET has always supported two layers of abstraction, though: ➤ System.Web.UI : The Web Forms layer, comprising server controls, ViewState, and so on read more..

  • Page - 39

    A Quick Introduction to ASP.NET MVC ❘ 3 MVC as Applied to Web Frameworks The MVC pattern is used frequently in web programming. With ASP.NET MVC, it’s translated roughly as: ➤ Models: These are the classes that represent the domain you are interested in. These domain objects often encapsulate data stored in a database as well as code that read more..

  • Page - 40

    4 ❘ CHAPTER 1 GETTING STARTED important to understand how we got here. This section describes the contents and background of each of the three major ASP.NET MVC releases. DON’T PANIC! We list some MVC-specifi c features in this section that might not all make sense to you if you’re new to MVC. Don’t worry! We explain some context read more..

  • Page - 41

    A Quick Introduction to ASP.NET MVC ❘ 5 It also had lots of API enhancements and “pro” fe atures, based on feedback from developers build- ing a variety of applications on ASP.NET MVC 1, such as: ➤ Support for partitioning large applications into areas ➤ Asynchronous controllers support ➤ Support for rendering subsections of a page/site using read more..

  • Page - 42

    6 ❘ CHAPTER 1 GETTING STARTED <h3><em><%: Model.Genre.Name %></em> Albums</h3> <ul id="album-list"> <% foreach (var album in Model.Albums) { %> <li> <a href="<%: Url.Action("Details", new { id = album.AlbumId }) %>"> <img alt="<%: read more..

  • Page - 43

    A Quick Introduction to ASP.NET MVC ❘ 7 ➤ Mobile project template using jQuery Mobile ➤ Display modes ➤ Task support for asynchronous controllers ➤ Bundling and minifi cation Because MVC 4 is still a pretty recent release, we explain a few of these features in a little more detail here and describe them in more read more..

  • Page - 44

    8 ❘ CHAPTER 1 GETTING STARTED of the standard MVC fi lters (like a service-optimized [Authorize] attribute) and custom fi lters. ➤ Scaffolding: You add new Web API controllers using the same dialog used to add an MVC controller (as described later this chapter). You have the option to use the Add Controller dialog to quickly scaffold a Web API controller read more..

  • Page - 45

    A Quick Introduction to ASP.NET MVC ❘ 9 opportunity to move MVC beyond System.Web , which means it can more easily merge with Web API to form a next generation web stack. The goal is to support MVC 5 with minimal breaking changes. The.NET Web Development and Tools blog announcement post lists some of these plans as follows: ➤ MVC, read more..

  • Page - 46

    10 ❘ CHAPTER 1 GETTING STARTED You fi nd out more about Display modes in the mobile web discussion in Chapter 16. Bundling and Minifi cation ASP.NET MVC 4 (and later) supports the same bundling and minifi cation framework included in ASP.NET 4.5. This system reduces requests to your site by combining several individual script references into read more..

  • Page - 47

    ASP.NET MVC 5 Overview ❘ 11 code submissions are reviewed and tested by the ASP.NET team, and when released Microsoft will support them just as they have any of the previous ASP.NET MVC releases. Even if you’re not planning to contribute any source code, the public repository makes a huge differ- ence in visibility. Although in the past read more..

  • Page - 48

    12 ❘ CHAPTER 1 GETTING STARTED example, if you change your mind later on, you can use ASP.NET Scaffolding to add MVC to any existing ASP.NET application. New Web Project Experience As part of the new One ASP.NET experience, the dialogs for creating a new MVC application in Visual Studio 2013 have been merged and simplifi ed. You fi nd out read more..

  • Page - 49

    ASP.NET MVC 5 Overview ❘ 13 ➤ NuGet distribution: ASP.NET Identity is installed in your applications as a NuGet package. This means you can install it separately, as well as upgrade to newer releases with the sim- plicity of updating a single NuGet package. We’ll discuss ASP.NET Identity in more detail in Chapter 7. Bootstrap Templates The visual design of read more..

  • Page - 50

    14 ❘ CHAPTER 1 GETTING STARTED FIGURE 1-2 What’s even nicer is that, because the Bootstrap framework has broad acceptance across the web developer community, a large variety of Bootstrap themes (both free and paid) are available from sites like and . For example, Figure 1-3 shows a default MVC 5 application read more..

  • Page - 51

    ASP.NET MVC 5 Overview ❘ 15 system works in any ASP.NET application. Additionally, it includes support for building powerful custom scaffolders, complete with custom dialogs and a comprehensive scaffolding API. Chapters 3 and 4 describe scaffolding basics, and Chapter 16 explains two ways you can extend the scaffolding system. FIGURE 1-3 Authentication Filters read more..

  • Page - 52

    16 ❘ CHAPTER 1 GETTING STARTED Chapter 15 describes fi lters in detail, including fi lter overrides. INSTALLING MVC 5 AND CREATING APPLICATIONS The best way to learn about how MVC 5 works is to get started by building an application, so let’s do that. Software Requirements for ASP.NET MVC 5 MVC 5 requires .NET 4.5. As such, it runs on the read more..

  • Page - 53

    Installing MVC 5 and Creating Applications ❘ 17 Creating an ASP.NET MVC 5 Application You can create a new MVC 5 application using either Visual Studio 2013 or Visual Studio 2013 Express for Web 2013. The experience in both IDEs is very similar; because this is a Professional Series book we focus on Visual Studio development, read more..

  • Page - 54

    18 ❘ CHAPTER 1 GETTING STARTED FIGURE 1-5 3. Select ASP.NET Web Application, name your application MvcMusicStore, and click OK. ONE ASP.NET PROJECT TEMPLATE Note that there isn’t an MVC project type; there’s just an ASP.NET Web Application. Whereas previous versions of Visual Studio and ASP.NET used a dif- ferent project type for MVC, in read more..

  • Page - 55

    Installing MVC 5 and Creating Applications ❘ 19 ➤ Confi gure authentication ➤ Windows Azure (Visual Studio 2013.2 and later) FIGURE 1-6 The fi rst two selections (Select a Template and Add Folders and Core References For) work together. The template selects the starting point, but then you can use the framework checkboxes to add support for Web read more..

  • Page - 56

    20 ❘ CHAPTER 1 GETTING STARTED MVC,” “mostly Web API,” or “mostly Web Forms” application. This section reviews those tem- plates now. Remember, though, they’re just conveniences in Visual Studio 2013 rather than require- ments; you could start with an Empty template and add in MVC support two weeks later by adding the NuGet packages. read more..

  • Page - 57

    Installing MVC 5 and Creating Applications ❘ 21 NOTE Changes to the Facebook API have caused authorization redirection issues with this template at the time of this writing, as detailed in this CodePlex issue: . The fi x will likely require updating or replacing the Microsoft.AspNet.Mvc.Facebook NuGet read more..

  • Page - 58

    22 ❘ CHAPTER 1 GETTING STARTED Confi guring Authentication You can choose the authentication method by clicking the Change Authentication button, which then opens the Change Authentication dialog, as shown in Figure 1-7. FIGURE 1-7 There are four options: ➤ No Authentication: Used for an application that requires no authentication, such as a public website read more..

  • Page - 59

    Installing MVC 5 and Creating Applications ❘ 23 FIGURE 1-8 FIGURE 1-9 read more..

  • Page - 60

    24 ❘ CHAPTER 1 GETTING STARTED New MVC projects include a Project_Readme.html fi le in the root of the application. This fi le is automatically displayed when your project is created, as shown in Figure 1-9. It is completely self- contained—all styles are included via HTML style tags, so when you’re done with it you can just read more..

  • Page - 61

    The MVC Application Structure ❘ 25 DIRECTORY P URPOSE /fonts The Bootstrap template system includes some custom web fonts, which are placed in this directory /Content Where you put CSS, images, and other site content, other than scripts /App_Data Where you store data fi les you want to read/write /App_Start Where you put confi guration code for features like Routing, read more..

  • Page - 62

    26 ❘ CHAPTER 1 GETTING STARTED ➤ The /Views directory, you’ll fi nd that three subdirectories—/Account, /Home , and / Shared —as well as several template fi les within them, were also added to the project by default (Figure 1-12). FIGURE 1-12 ➤ The /Content and /Scripts directories, you’ll fi nd the CSS fi les that is used to style all HTML read more..

  • Page - 63

    The MVC Application Structure ❘ 27 FIGURE 1-13 ASP.NET MVC and Conventions ASP.NET MVC applications, by default, rely heavily on conventions. This allows developers to avoid having to confi gure and specify things that can be inferred based on convention. For instance, MVC uses a convention-based directory-naming structure when resolving View tem- plates, and this read more..

  • Page - 64

    28 ❘ CHAPTER 1 GETTING STARTED FIGURE 1-14 Convention over Confi guration The convention over confi guration concept was made popular by Ruby on Rails a few years back, and essentially means: “We know, by now, how to build a web application. Let’s roll that experience into the framework so we don’t have to confi gure absolutely read more..

  • Page - 65

    Summary ❘ 29 This isn’t meant to be magical. Well, actually, it is; it’s just not meant to be black magic—the kind of magic where you may not get the outcome you expected (and moreover can actually harm you). ASP.NET MVC’s conventions are pretty straightforward. This is what is expected of your applica- tion’s structure: ➤ read more..

  • Page - 66

    30 ❘ CHAPTER 1 GETTING STARTED REMINDER FOR ADVANCED READERS As mentioned in the introduction, the fi rst six chapters of this book are intended to provide a fi rm foundation in the fundamentals of ASP.NET MVC. If you already have a pretty good grasp of how ASP.NET MVC works, you might want to skip ahead to Chapter 7. read more..

  • Page - 67

    Controllers —by Jon Galloway WHAT’S IN THIS CHAPTER? ➤ Understanding the controller’s role ➤ Setting up a sample application: The MVC Music Store ➤ Controller 101 This chapter explains how controllers respond to user HTTP requests and return information to the browser. It focuses on the function of controllers and controller actions. We haven’t read more..

  • Page - 68

    32 ❘ CHAPTER 2 CONTROLLERS that were also located on disk. With MVC, it’s a little different. The URL tells the routing mechanism (which you’ll begin to explore in the next few chapters, and learn about in depth in Chapter 9) which controller class to instantiate and which action method to call, and supplies the required arguments to that read more..

  • Page - 69

    The Controller’s Role ❘ 33 Digging under the hood a bit, however, reveals that a lot of work is going on to simulate that componentized event-driven experience. At its core, when a button is clicked, the browser submits a request to the server containing the state of the controls on the page encapsulated in an encoded hidden input. On read more..

  • Page - 70

    34 ❘ CHAPTER 2 CONTROLLERS A SAMPLE APPLICATION: THE MVC MUSIC STORE As mentioned in Chapter 1, we will use the MVC Music Store application for a lot of our samples in this book. You can fi nd out more about the MVC Music Store application at http:// . The Music Store tutorial is intended for beginners and moves at a read more..

  • Page - 71

    A Sample Application: The MVC Music Store ❘ 35 The following store features are covered: ➤ Browse: Browse through music by genre and artist, as shown in Figure 2-2. FIGURE 2-2 ➤ Add: Add songs to your cart, as shown in Figure 2-3. read more..

  • Page - 72

    36 ❘ CHAPTER 2 CONTROLLERS FIGURE 2-3 ➤ Shop: Update shopping cart (with Ajax updates), as shown in Figure 2-4. FIGURE 2-4 read more..

  • Page - 73

    A Sample Application: The MVC Music Store ❘ 37 ➤ Order: Create an order and check out, as shown in Figure 2-5. FIGURE 2-5 ➤ Administer: Edit the song list (restricted to administrators), as shown in Figure 2-6. read more..

  • Page - 74

    38 ❘ CHAPTER 2 CONTROLLERS FIGURE 2-6 CONTROLLER BASICS Getting started with MVC presents something of a chicken and egg problem: There are three parts (model, view, and controller) to understand, and really digging into one of those parts without understanding the others is diffi cult. To get started, you’ll fi rst learn about controllers at a read more..

  • Page - 75

    Controller Basics ❘ 39 A Simple Example: The Home Controller Before writing any real code, let’s start by looking at what’s included by default in a new project. Projects created using the MVC template with Individual User Accounts include two controller classes: ➤ HomeController : Responsible for the “home page” at the root of the website, as read more..

  • Page - 76

    40 ❘ CHAPTER 2 CONTROLLERS using System.Web; using System.Web.Mvc; namespace MvcMusicStore.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult About() { read more..

  • Page - 77

    Controller Basics ❘ 41 FIGURE 2-8 4. Navigate to the About page by browsing to /Home/About (or by clicking the About link in the header). Your updated message displays, as shown in Figure 2-9. FIGURE 2-9 Great—you created a new project and put some words on the screen! Now let’s get to work on building an actual application by creating a new read more..

  • Page - 78

    42 ❘ CHAPTER 2 CONTROLLERS Writing Your First Controller In this section, you’ll create a controller to handle URLs related to browsing through the music catalog. This controller will support three scenarios: ➤ The index page lists the music genres that your store carries. ➤ Clicking a genre leads to a browse page that lists all the music read more..

  • Page - 79

    Controller Basics ❘ 43 2. Select the MVC 5 Controller - Empty scaffolding template, as shown in Figure 2-11. FIGURE 2-11 3. Name the controller StoreController and press the Add button, as shown in Figure 2-12. FIGURE 2-12 Writing Your Action Methods Your new StoreController already has an Index method. You’ll use this Index method to implement read more..

  • Page - 80

    44 ❘ CHAPTER 2 CONTROLLERS To get an idea of how a controller action works, follow these steps: 1. Change the signature of the Index method to return a string (rather than an ActionResult ) and change the return value to "Hello from Store.Index()" as follows: // // GET: /Store/ public string read more..

  • Page - 81

    Controller Basics ❘ 45 FIGURE 2-13 A Few Quick Observations Let’s draw some conclusions from this quick experiment: ➤ Browsing to /Store/Details caused the Details method of the StoreController class to be executed, without any additional confi guration. This is routing in action. We’ll talk a little more about routing later in this chapter and go into read more..

  • Page - 82

    46 ❘ CHAPTER 2 CONTROLLERS HTML ENCODING USER INPUT We’re using the HttpUtility.HtmlEncode utility method to sanitize the user input. This prevents users from injecting JavaScript code or HTML markup into our view with a link like /Store/Browse?Genre=<script>window.location='http://'</script> . 2. Browse to /Store/Browse?Genre=Disco read more..

  • Page - 83

    Summary ❘ 47 FIGURE 2-15 As the preceding examples indicate, you can look at controller actions as if the web browser were directly calling methods on your controller class. The class, method, and parameters are all speci- fi ed as path segments or query strings in the URL, and the result is a string that’s returned to the browser. read more..

  • Page - 84

    read more..

  • Page - 85

    Views —by Phil Haack and Jon Galloway WHAT’S IN THIS CHAPTER? ➤ The purpose of views ➤ Understanding view basics ➤ View conventions 101 ➤ All about strongly typed views ➤ Understanding view models ➤ How to add a view ➤ Using Razor ➤ How to specify a partial view WROX.COM CODE DOWNLOADS FOR THIS CHAPTER All code for this chapter is read more..

  • Page - 86

    50 ❘ CHAPTER 3 VIEWS The view is effectively your application’s ambassador to the user. Obviously, if the rest of your application is buggy, no amount of spit and polish on the view will make up for the application’s shortcomings. Likewise, build an ugly and hard-to-use view, and many users will not give your application a chance read more..

  • Page - 87

    View Basics ❘ 51 doesn’t need any information from the controller. Open the /Views/Home/Index.cshtml fi le (see Listing 3-1) from the project you created in Chapter 2 (or in any new MVC 5 project). LISTING 3-1: Home Index view—Index.cshtml @{ ViewBag.Title = "Home Page"; } <div class="jumbotron"> <h1>ASP.NET</h1> read more..

  • Page - 88

    52 ❘ CHAPTER 3 VIEWS Aside from the tiny bit of code at the top that sets the page title, this is all just standard HTML. Listing 3-2 shows the controller that initiated this view: LISTING 3-2: Home Index method—HomeController.cs public ActionResult Index() { return View(); } Browsing to the root of the site (as shown in Figure 3-1) read more..

  • Page - 89

    View Basics ❘ 53 has limitations, but it can be useful if you’re just passing a little data to the view. Take a look at the About action method in HomeController.cs , shown in Listing 3-3. LISTING 3-3: Home About method—HomeController.cs public ActionResult About() { ViewBag.Message = "Your application description page."; read more..

  • Page - 90

    54 ❘ CHAPTER 3 VIEWS UNDERSTANDING VIEW CONVENTIONS In the previous section, you looked at some examples that illustrate how to use views to render HTML. In this section, you learn how ASP.NET MVC fi nds the correct view to render and how you can override this to specify a particular view for a controller action. The controller actions read more..

  • Page - 91

    Strongly Typed Views ❘ 55 As with most things in ASP.NET MVC, you can override this convention. Suppose that you want the Index action to render a different view. You could supply a different view name, as follows: public ActionResult Index() { return View("NotIndex"); } In this case, it will still look in the read more..

  • Page - 92

    56 ❘ CHAPTER 3 VIEWS <li>@a.Title</li> } </ul> Notice that you needed to cast ViewBag.Albums (which is dynamic) to an IEnumerable<Album> before enumerating it. You could have also used the dynamic keyword here to clean the view code up, but you would have lost the benefi t of IntelliSense when accessing the properties of read more..

  • Page - 93

    Strongly Typed Views ❘ 57 @foreach (Album p in Model) { <li>@p.Title</li> } </ul> An even better approach for namespaces, which you’ll end up using often in views, is to declare the namespace in the web.config fi le within the Views directory. <system.web.webPages.razor> … <pages pageBaseType="System.Web.Mvc.WebViewPage"> read more..

  • Page - 94

    58 ❘ CHAPTER 3 VIEWS Generally, most current code you’ll encounter uses ViewBag rather than ViewData . For the most part, you don’t have a real technical advantage when choosing one syntax over the other. ViewBag is just syntactic sugar that some people prefer over the dictionary syntax. It just looks nicer. VIEWDATA AND VIEWBAG read more..

  • Page - 95

    View Models ❘ 59 LISTING 3-5: Populating dropdowns via ViewBag // // GET: /StoreManager/Edit/5 public ActionResult Edit(int id = 0) { Album album = db.Albums.Find(id); if (album == null) { return HttpNotFound(); } ViewBag.GenreId = new SelectList( read more..

  • Page - 96

    60 ❘ CHAPTER 3 VIEWS The preceding sections introduced a few concepts associated with models as they relate to the view. The following chapter discusses models in much greater detail. ADDING A VIEW In the “View Basics” and “View Conventions” sections you learned how a controller specifi es a view. But how does that view get created in read more..

  • Page - 97

    Adding a View ❘ 61 FIGURE 3-5 FIGURE 3-6 read more..

  • Page - 98

    62 ❘ CHAPTER 3 VIEWS TABLE 3-1: View Scaffold Types SCAFFOLD DESCRIPTION Create Creates a view with a form for generating new instances of the model. Generates a label and input fi eld for each property of the model type. Delete Creates a view with a form for deleting existing instances of the model. Displays a label and the current value for each property read more..

  • Page - 99

    The Razor View Engine ❘ 63 ➤ Create as a partial view: Selecting this option indicates that the view you will create is not a full view, thus the Layout option is disabled. The resulting partial view looks much like a regular view, except you’ll have no <html> tag or <head> tag at the top of the view. ➤ Use a layout page: This option read more..

  • Page - 100

    64 ❘ CHAPTER 3 VIEWS and your view markup. Many developers who have written Razor views have commented on feeling the view code just fl owing from their fi ngertips, akin to a mind-meld with their keyboard. This feel- ing is enhanced with the fi rst-rate IntelliSense support for Razor in Visual Studio. Razor accomplishes this by read more..

  • Page - 101

    The Razor View Engine ❘ 65 For example, in the following snippet: <h1>Listing @items.Length items.</h1> notice that the expression @stuff.length is evaluated as an implicit code expression and the result, 3, is displayed in the output. One thing to notice, though, is that we didn’t need to demarcate the end of the code expression. In read more..

  • Page - 102

    66 ❘ CHAPTER 3 VIEWS NOTE Razor uses a simple algorithm to determine whether something looks like an e-mail address. It’s not meant to be perfect, but it handles most cases. Some valid e-mails might appear not to be e-mails, in which case you can always escape the @ sign with an @@ sign. But, of course, what if read more..

  • Page - 103

    The Razor View Engine ❘ 67 This code does not result in an alert box popping up but instead renders the encoded HTML: <span>&lt;script&gt;alert(&#39;haacked!&#39;);&lt;/script&gt;</span> However, in cases where you intend to show HTML markup, you can return an instance of System .Web.IHtmlString and Razor will not encode it. For read more..

  • Page - 104

    68 ❘ CHAPTER 3 VIEWS Code Blocks In addition to code expressions, Razor also supports code blocks within a view. Going back to the sample view, you might remember seeing a foreach statement: @foreach(var item in stuff) { <li>The item name is @item.</li> } This block of code iterates over an array and displays a list item element for read more..

  • Page - 105

    The Razor View Engine ❘ 69 Code expressions in Razor are always HTML encoded. Explicit Code Expression Code expressions are evaluated and written to the response. This is typically how you display a value in a view: <span>1 + 2 = @(1 + 2)</span> Unencoded Code Expression In some cases, you need to explicitly render some value that read more..

  • Page - 106

    70 ❘ CHAPTER 3 VIEWS Escaping the Code Delimiter As you saw earlier in this chapter, you can display @ by encoding it using @@ . Alternatively, you always have the option to use HTML encoding: Razor: The ASP.NET Twitter Handle is &#64;aspnet or The ASP.NET Twitter Handle is @@aspnet Server-Side Comment Razor includes a nice syntax for commenting read more..

  • Page - 107

    The Razor View Engine ❘ 71 It looks like a standard Razor view, but note that there’s a call to @RenderBody in the view. This is a placeholder that marks the location where views using this layout will have their main content rendered. Multiple Razor views may now take advantage of this layout to enforce a consistent look and read more..

  • Page - 108

    72 ❘ CHAPTER 3 VIEWS The @section syntax specifi es the contents for a section defi ned in the layout. Earlier, it was pointed out that, by default, a view must supply content for every defi ned section. So what happens when you want to add a new section to a layout? Will that break every view? Fortunately, the RenderSection read more..

  • Page - 109

    Specifying a Partial View ❘ 73 You can use the _ViewStart.cshtml page to remove this redundancy. The code within this fi le is executed before the code in any view placed in the same directory. This fi le is also recursively applied to any view within a subdirectory. When you create a default ASP.NET MVC project, you’ll notice a read more..

  • Page - 110

    74 ❘ CHAPTER 3 VIEWS To see the examples of specifying views and partial views described in the previous two sections, use NuGet to install the Wrox.ProMvc5.Views.SpecifyingViews package into a default ASP.NET MVC 5 project, as follows: Install-Package Wrox.ProMvc5.Views.SpecifyingViews This adds a sample controller to your project in the samples directory with read more..

  • Page - 111

    Models —by K. Scott Allen and Jon Galloway WHAT’S IN THIS CHAPTER? ➤ How to model the Music Store ➤ What it means to scaffold ➤ How to edit an album ➤ All about model binding WROX.COM CODE DOWNLOADS FOR THIS CHAPTER You can fi nd the code downloads for this chapter at proaspnetmvc5 on the Download Code tab. read more..

  • Page - 112

    76 ❘ CHAPTER 4 MODELS ASP.NET MVC 5 provides a number of tools and features to build out application features using only the defi nition of model objects. You can sit down and think about the problem you want to solve (like how to let a customer buy music), and write plain C# classes, such as Album , ShoppingCart , and User , to read more..

  • Page - 113

    Modeling the Music Store ❘ 77 After you give the project a name, Visual Studio opens the dialog you see in Figure 4-2, and you can tell Visual Studio you want to work with the MVC project template. FIGURE 4-2 The MVC template gives you everything you need to get started: a basic layout view, a default homepage with a link for a read more..

  • Page - 114

    78 ❘ CHAPTER 4 MODELS FIGURE 4-3 LISTING 4-1: Album model public class Album { public virtual int AlbumId { get; set; } public virtual int GenreId { get; set; } public virtual int ArtistId { get; set; } public virtual string Title { get; set; } public virtual decimal Price { get; set; } read more..

  • Page - 115

    Modeling the Music Store ❘ 79 The primary purpose of the album model is to simulate attributes of a music album, such as the title and the price. Every album also has an association with a single artist, which you’ll model using a new Artist class. To do so, add a new Artist class to the Models folder and enter the properties read more..

  • Page - 116

    80 ❘ CHAPTER 4 MODELS You might also notice that every property is virtual. We discuss why the properties are virtual later in this chapter. For now, these three simple class defi nitions are your starting models and include everything you need to scaffold out a controller and some views and even create a database. Now that you’ve read more..

  • Page - 117

    Scaffolding a Store Manager ❘ 81 SCAFFOLDING OPTIONS Like nearly everything else in the MVC framework, if you don’t like the default scaffolding behavior, you can customize or replace the code generation strategy to fulfi ll your own desires. You can also fi nd alternative scaffolding templates through NuGet (just search for scaffolding). read more..

  • Page - 118

    82 ❘ CHAPTER 4 MODELS For the template to generate the proper code, you have to select a model class (in this case, you use the Album class). The scaffolding examines all the properties of your model and uses the information it fi nds to build controllers, views, and data access code. To generate the data access code, the read more..

  • Page - 119

    Scaffolding a Store Manager ❘ 83 Code First Conventions EF, like ASP.NET MVC, follows a number of conventions to make your life easier. For example, if you want to store an object of type Album in the database, EF assumes you want to store the data in a table named Albums . If you have a property on the object named ID, EF read more..

  • Page - 120

    84 ❘ CHAPTER 4 MODELS Using the preceding data context, you can retrieve all albums in alphabetical order using the LINQ query in the following code: var db = new MusicStoreDB(); var allAlbums = from album in db.Albums orderby album.Title ascending select album; Now that you know a little read more..

  • Page - 121

    Scaffolding a Store Manager ❘ 85 Executing the Scaffolding Template Okay! We’ve covered all the necessary theory, so now it’s time to scaffold a controller! Just follow these steps: 1. Right-click the Controllers folder and select Add ➪ Controller. The Add Scaffold dialog appears, as shown in Figure 4-4. The Add Scaffold dialog lists the scaffold templates read more..

  • Page - 122

    86 ❘ CHAPTER 4 MODELS WHAT’S CHANGED IN VISUAL STUDIO 2013 AND MVC 5 If you’ve used prior versions of ASP.NET MVC, you’ll notice that there’s an extra step here. Previously, the scaffold template selection was included in the Add Controller dialog. When you changed the template, other fi elds on this dialog changed to match the read more..

  • Page - 123

    Scaffolding a Store Manager ❘ 87 5. Name your context MusicStoreDB, as shown in Figure 4-6, and click the Add button to set the context name. Because the Add Controller dialog now contains all required information, the Add button is now enabled. FIGURE 4-6 6. Verify that your dialog matches the example shown in Figure 4-7 and click the Add button to scaffold read more..

  • Page - 124

    88 ❘ CHAPTER 4 MODELS LISTING 4-4: MusicStoreDB (DbContext) public class MusicStoreDB : DbContext { // You can add custom code to this file. Changes will not be overwritten. // // If you want Entity Framework to drop and regenerate your database // automatically whenever you change your model schema, // please use data migrations. // For more read more..

  • Page - 125

    Scaffolding a Store Manager ❘ 89 To access a database, all you need to do is instantiate the data context class. You might be wondering what database the context will use. That question is answered later when you fi rst run the application. The StoreManagerController The scaffolding template you selected also generates a StoreManagerController read more..

  • Page - 126

    90 ❘ CHAPTER 4 MODELS described is known as the N+1 problem (because the framework executes 101 total queries to bring back 100 populated objects), and is a common problem to face when using an object-relational mapping framework. Lazy loading is convenient, but potentially expensive. You can think of Include as an optimization to reduce the read more..

  • Page - 127

    Scaffolding a Store Manager ❘ 91 The Index view has all the code needed to display a table full of music albums. The model for the view is an enumerable sequence of Album objects, and as you saw in the Index action earlier, an enumerable sequence of Album objects is precisely what the Index action delivers. The view read more..

  • Page - 128

    92 ❘ CHAPTER 4 MODELS Each table row also includes links to edit, delete, and detail an album. As mentioned earlier, the scaffolded code you are looking at is just a starting point. You probably want to add, remove, and change some of the code and tweak the views to your exact specifi cations. But, before you make changes, you read more..

  • Page - 129

    Scaffolding a Store Manager ❘ 93 application after scaffolding completes, and navigate to the /StoreManager URL, you’ll discover that the EF has created a database named MvcMusicStore.Models.MusicStoreDB in LocalDB. If you look at an Entity Data Model diagram of the new database, you’ll see what’s shown in Figure 4-9. The EF automatically read more..

  • Page - 130

    94 ❘ CHAPTER 4 MODELS If you change your model (by adding a property, removing a property, or adding a class, for example), EF can use the information stored in the __MigrationHistory table to determine what has changed, and either re-creates the database based on your new model, or throws an exception. Don’t worry—EF will not re-create read more..

  • Page - 131

    Scaffolding a Store Manager ❘ 95 You might be wondering why anyone would want to re-create a database from scratch every time an application restarts. Even when the model changes, don’t you want to preserve the data inside? These questions are valid, and you’ll have to remember that features in the code-fi rst approach (like the database read more..

  • Page - 132

    96 ❘ CHAPTER 4 MODELS work, you need to change the application startup code to register the initializer, as shown in Listing 4-8. LISTING 4-8: Global.asax.cs protected void Application_Start() { Database.SetInitializer(new MusicStoreDbInitializer()); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); read more..

  • Page - 133

    Editing an Album ❘ 97 INITIALIZER SEEDS VERSUS MIGRATION SEEDS Migrations also support seed methods, so when you make the move from the quick and easy database initializer approach to the more sophisticated migra- tions approach, you’ll want to convert any necessary seed methods to work with your migrations. You need to be aware of an read more..

  • Page - 134

    98 ❘ CHAPTER 4 MODELS } Album album = db.Albums.Find(id); if (album == null) { return HttpNotFound(); } ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); ViewBag.GenreId = new SelectList(db.Genres, "GenreId", read more..

  • Page - 135

    Editing an Album ❘ 99 The scaffolding is smart enough to realize this, too, because it understands the association between album, artist, and genre. Instead of giving the user a textbox to type into, the scaffolding generates an edit view with a drop- down list to select an existing genre, as shown in Figure 4-12. FIGURE 4-12 The following read more..

  • Page - 136

    100 ❘ CHAPTER 4 MODELS ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId); The SelectList class that the code uses represents the data required to build a drop-down list. The fi rst parameter to the constructor read more..

  • Page - 137

    Editing an Album ❘ 101 <input type="submit" value="Save" /> </p> } The view includes a form with a variety of inputs for a user to enter information. Some of the inputs are drop-down lists (HTML <select> elements), and others are textbox controls (HTML <input type= ˝text˝> elements). The essence of read more..

  • Page - 138

    102 ❘ CHAPTER 4 MODELS db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); ViewBag.GenreId = new SelectList(db.Genres, read more..

  • Page - 139

    Model Binding ❘ 103 FIGURE 4-13 MODEL BINDING Imagine you implemented the Edit action for an HTTP POST, and you didn’t know about any of the ASP.NET MVC features that can make your life easy. Because you are a professional web developer, you realize the Edit view is going to post form values to the server. If you want to retrieve read more..

  • Page - 140

    104 ❘ CHAPTER 4 MODELS As you can imagine, code like this becomes quite tedious. I’ve only shown the code to set two properties; you have four or fi ve more to go. You have to pull each property value out of the Form collection (which contains all the posted form values, by name) and move those values into Album properties. read more..

  • Page - 141

    Model Binding ❘ 105 Edit/1 , but it is a model binder that converts and moves the value from route data into the id parameter. You could also invoke this action using the URL /StoreManager/Edit?id=1 , because the model binder will fi nd the id parameter in the query string collection. The model binder is a bit like a search-and-rescue dog. read more..

  • Page - 142

    106 ❘ CHAPTER 4 MODELS { UpdateModel(album); db.Entry(album).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } catch read more..

  • Page - 143

    Summary ❘ 107 { db.Entry(album).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } else { ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", read more..

  • Page - 144

    108 ❘ CHAPTER 4 MODELS Framework, but scaffolding is extensible and customizable, so you can have scaffolding work with a variety of technologies. You also looked at model binding and should now understand how to capture values in a request using the model binding features instead of digging around in form collections and query strings in your read more..

  • Page - 145

    Forms and HTML Helpers —by K. Scott Allen WHAT’S IN THIS CHAPTER? ➤ Understanding forms ➤ Making HTML helpers work for you ➤ Editing and inputting helpers ➤ Displaying and rendering helpers WROX.COM CODE DOWNLOADS FOR THIS CHAPTER You can fi nd the code downloads for this chapter at proaspnetmvc5 on the Download Code read more..

  • Page - 146

    110 ❘ CHAPTER 5 FORMS AND HTML HELPERS USING FORMS You might wonder why a book targeted at professional web developers covers the HTML form tag. Isn’t it easy to understand? There are two reasons: ➤ The form tag is powerful. Without the form tag, the Internet would be a read-only repository of boring documentation. You wouldn’t be able to read more..

  • Page - 147

    Using Forms ❘ 111 To GET or to POST? You can also give the method attribute the value post , in which case the browser does not place the input values into the query string, but places them inside the body of the HTTP request instead. Although you can successfully send a POST request to a search engine and see the search results, read more..

  • Page - 148

    112 ❘ CHAPTER 5 FORMS AND HTML HELPERS NOTE In this section, we’re using some examples based on a completed Music Store to illustrate the use of a form with a GET method instead of a POST method. Don’t worry about typing this code in. The next step is to implement a Search method on the HomeController . The code block read more..

  • Page - 149

    Using Forms ❘ 113 <tr> <td>@item.Artist.Name</td> <td>@item.Title</td> <td>@String.Format("{0:c}", item.Price)</td> </tr> } </table> The result lets customers search for terms such as “work,” wh ich produces the output shown in Figure 5-2. FIGURE 5-2 The simple search read more..

  • Page - 150

    114 ❘ CHAPTER 5 FORMS AND HTML HELPERS Searching for Music by Calculating the Action Attribute Value Rather than hard-coding the form behavior, a better approach is to calculate the value of the action attribute, and fortunately, there is an HTML helper to do the calculation for you. @using (Html.BeginForm("Search", "Home", FormMethod.Get)) { read more..

  • Page - 151

    HTML Helpers ❘ 115 routing engine to generate a proper URL, so the code is more resilient to changes in the application deployment location. Note the BeginForm helper outputs both the opening <form> and the closing </form> . The helper emits the opening tag during the call to BeginForm , and the call returns an object implementing read more..

  • Page - 152

    116 ❘ CHAPTER 5 FORMS AND HTML HELPERS { <input type="text" name="q" /> <input type="submit" value="Search" /> } In this code, you are passing an anonymously typed object to the htmlAttributes parameter of BeginForm . Nearly every HTML helper in the MVC framework includes an htmlAttributes parameter in one of read more..

  • Page - 153

    HTML Helpers ❘ 117 in a view, such as EnableClientValidation (to selectively turn client validation on or off on a view-by-view basis). However, the BeginForm method you used in the previous section is not one of the methods you’ll fi nd defi ned on the class. Instead, the framework defi nes the majority of the help- ers as read more..

  • Page - 154

    118 ❘ CHAPTER 5 FORMS AND HTML HELPERS POST is the ideal verb for this scenario because you are modifying album information on the server. Html.ValidationSummary The ValidationSummary helper displays an unordered list of all validation errors in the ModelState dictionary. The Boolean parameter you are using (with a value of true ) is telling the read more..

  • Page - 155

    HTML Helpers ❘ 119 <div class="form-horizontal"> <h4>Album</h4> <hr /> @Html.ValidationSummary(true) @Html.HiddenFor(model => model.AlbumId) <div class="form-group"> @Html.LabelFor(model => model.GenreId, read more..

  • Page - 156

    120 ❘ CHAPTER 5 FORMS AND HTML HELPERS <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Save" class="btn btn-default" /> </div> </div> </div> } As a reminder, these helpers give the user the read more..

  • Page - 157

    HTML Helpers ❘ 121 ➤ ValidationSummary ➤ HiddenFor We talk about all of these—and more—in this section. To begin with, though, you’ll start with the simplest input HTML helper: the TextBox helper. Html.TextBox and Html.TextArea The TextBox helper renders an input tag with the type attribute set to text . You commonly use the read more..

  • Page - 158

    122 ❘ CHAPTER 5 FORMS AND HTML HELPERS inputs, and boost the accessibility of your application. The for attribute of the label should con- tain the ID of the associated input element (in this example, the drop-down list of genres that fol- lows in the HTML). Screen readers can use the text of the label to provide a read more..

  • Page - 159

    HTML Helpers ❘ 123 SelectList constructor specify the original collection (Genres from the database), the name of the property to use as a value (GenreId), the name of the property to use as the text (Name), and the value of the currently selected item (to determine which item to mark as selected). If you want to avoid some refl read more..

  • Page - 160

    124 ❘ CHAPTER 5 FORMS AND HTML HELPERS This message appears only if there is an error in the model state for the key Title . You can also call an override that allows you to override the error message from within the view: @Html.ValidationMessage("Title", "Something is wrong with your title") which results in <span read more..

  • Page - 161

    HTML Helpers ❘ 125 { ViewBag.Album = new Album {Price = 11}; return View(); } You can use the following code to display a textbox with the album’s price: @Html.TextBox("Album.Price") Now the resulting HTML looks like the following code: <input read more..

  • Page - 162

    126 ❘ CHAPTER 5 FORMS AND HTML HELPERS Inside the edit view, which is strongly typed to an Album , you have the following code to render an input for the album title: @Html.TextBox("Title", Model.Title) The second parameter provides the data value explicitly. Why? Well, in this case, Title is a value already in ViewData , because the Music read more..

  • Page - 163

    HTML Helpers ❘ 127 Notice that the strongly typed helpers have the same names as the previous helpers you’ve been using, but with a For suffi x. The preceding code produces the same HTML you saw previously; however, replacing strings with lambda expressions provides a number of additional benefi ts. The benefi ts include read more..

  • Page - 164

    128 ❘ CHAPTER 5 FORMS AND HTML HELPERS Instead of using Html.TextBoxFor , you can switch to using the following code: @Html.EditorFor(m => m.Title The EditorFor helper will render the same HTML as TextBoxFor ; however, you can change the HTML using data annotations. If you think about the name of the helper (Editor), the name is more read more..

  • Page - 165

    Other Input Helpers ❘ 129 When ModelState contains an error for a given property, the form helper associated with the error renders a CSS class of input-validation-error in addition to any explicitly specifi ed CSS classes. The default style sheet, style.css , included in the project template contains styling for this class. OTHER INPUT HELPERS In read more..

  • Page - 166

    130 ❘ CHAPTER 5 FORMS AND HTML HELPERS The Html.RadioButton helper renders a simple radio button: @Html.RadioButton("color", "red") @Html.RadioButton("color", "blue", true) @Html.RadioButton("color", "green") and results in <input id="color" name="color" type="radio" value="red" /> <input checked="checked" read more..

  • Page - 167

    Rendering Helpers ❘ 131 Html.ActionLink and Html.RouteLink The ActionLink method renders a hyperlink (anchor tag) to another controller action. Like the BeginForm helper you looked at earlier, the ActionLink helper uses the routing API under the hood to generate the URL. For example, when linking to an action in the same controller used to render read more..

  • Page - 168

    132 ❘ CHAPTER 5 FORMS AND HTML HELPERS The RouteLink helper follows the same pattern as the ActionLink helper, but also accepts a route name and does not have arguments for controller name and action name. For example, the fi rst example ActionLink shown previously is equivalent to the following: @Html.RouteLink("Link Text", new read more..

  • Page - 169

    Rendering Helpers ❘ 133 Html.Partial and Html.RenderPartial The Partial helper renders a partial view into a string. Typically, a partial view contains reusable markup you want to render from inside multiple different views. Partial has four overloads: public void Partial(string partialViewName); public void Partial(string partialViewName, object model); public void read more..

  • Page - 170

    134 ❘ CHAPTER 5 FORMS AND HTML HELPERS [ChildActionOnly] public ActionResult Menu() { var menu = GetMenuFromSomewhere(); return PartialView(menu); } } The Menu action builds a menu model and returns a partial view with just the menu: @model Menu <ul> @foreach (var item in Model.MenuItem) { <li>@item.Text</li> } </ul> read more..

  • Page - 171

    Summary ❘ 135 3. You can pass in menu options from your action call in the view: @Html.Action("Menu", new { options = new MenuOptions { Width=400, Height=500 } }) Cooperating with the ActionName Attribute Another thing to note is that RenderAction honors the ActionName attribute when calling an action name. If you annotate the action as read more..

  • Page - 172

    read more..

  • Page - 173

    Data Annotations and Validation —by K. Scott Allen WHAT’S IN THIS CHAPTER? ➤ Using data annotations for validation ➤ Creating your own validation logic ➤ Using model metadata annotations WROX.COM CODE DOWNLOADS FOR THIS CHAPTER You can fi nd the code downloads for this chapter at go/proaspnetmvc5 on the Download Code tab. read more..

  • Page - 174

    138 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION When you talk about validation in an MVC design pattern context, you are primarily focusing on validating model values. Did the user provide a required value? Is the value in range? The ASP.NET MVC validation features can help you validate model values. The validation features are exten- sible—you read more..

  • Page - 175

    Annotating Orders for Validation ❘ 139 public decimal Total { get; set; } public List<OrderDetail> OrderDetails { get; set; } } Some of the properties in the Order class require user input (such as FirstName and LastName ), whereas the application derives other property values from the environment, or looks them up from the database (such read more..

  • Page - 176

    140 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION Next, run the application and browse to /Order/Create as shown in Figure 6-2. FIGURE 6-2 The form has some visible problems. For example, you do not want the customer to enter an OrderDate or the order Total amount. The application will set the values of these properties on the read more..

  • Page - 177

    Annotating Orders for Validation ❘ 141 server. Also, although the input labels might make sense to a developer (FirstName is obviously a property name), the labels will probably leave a customer bewildered (was someone’s spacebar bro- ken?). You’ll fi x these problems later in the chapter. For now, a more serious problem exists that you read more..

  • Page - 178

    142 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION { public int OrderId { get; set; } public DateTime OrderDate { get; set; } public string Username { get; set; } [Required] public string FirstName { get; set; } [Required] public string read more..

  • Page - 179

    Annotating Orders for Validation ❘ 143 public string FirstName { get; set; } [Required] [StringLength(160)] public string LastName { get; set; } FIGURE 6-3 Notice how you can stack multiple validation attributes on a single property. With the attribute in place, if customers enter too many characters, they’ll see the default error message shown below the LastName read more..

  • Page - 180

    144 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION MinimumLength is an optional, named parameter you can use to specify the minimum length for a string. The following code requires the FirstName property to contain a string with three or more characters (and less than or equal to 160 characters) to pass validation: [Required] [StringLength(160, read more..

  • Page - 181

    Annotating Orders for Validation ❘ 145 Compare Compare ensures two properties on a model object have the same value. For example, you might want to force customers to enter their e-mail address twice to ensure they didn’t make a typographi- cal error: [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")] public string Email { get; set; } read more..

  • Page - 182

    146 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION Remote only exists because data annotations are extensible. You look at building a custom annota- tion later in the chapter. For now, let’s look at customizing the error messages on display for a failed validation rule. Custom Error Messages and Localization Every validation attribute allows you to pass read more..

  • Page - 183

    Annotating Orders for Validation ❘ 147 ErrorMessageResourceName = "LastNameTooLong")] public string LastName { get; set; } The preceding code assumes you have a resource fi le in the project named ErrorMessages.resx with the appropriate entries inside (LastNameRequired and LastNameTooLong ). For ASP.NET to use localized resource fi read more..

  • Page - 184

    148 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION DataAnnotationsModelValidator ). This model validator can fi nd all the validation attributes and execute the validation logic inside. The model binder catches all the failed validation rules and places them into model state. Validation and Model State The primary side effect of model binding is model state read more..

  • Page - 185

    Annotating Orders for Validation ❘ 149 storeDB.Orders.Add(newOrder); storeDB.SaveChanges(); // Process the order var cart = ShoppingCart.GetCart(this); cart.CreateOrder(newOrder); return RedirectToAction("Complete", new { id = newOrder.OrderId }); } // Invalid read more..

  • Page - 186

    150 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION // Process the order var cart = ShoppingCart.GetCart(this); cart.CreateOrder(newOrder); return RedirectToAction("Complete", new { id = newOrder.OrderId }); } // Invalid -- redisplay with errors return View(newOrder); read more..

  • Page - 187

    Custom Validation Logic ❘ 151 with other models in the Music Store application. If so, the validation logic is a candidate for pack- aging into a reusable attribute. All the validation annotations (such as Required and Range ) ultimately derive from the ValidationAttribute base class. The base class is abstract and lives in the System read more..

  • Page - 188

    152 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION Now that you’ve parameterized the maximum word count, you can implement the validation logic to catch an error: public class MaxWordsAttribute : ValidationAttribute { public MaxWordsAttribute(int maxWords) { _maxWords = maxWords; } protected override ValidationResult IsValid( read more..

  • Page - 189

    Custom Validation Logic ❘ 153 validationContext.DisplayName); return new ValidationResult(errorMessage); } } return ValidationResult.Success; } private readonly int _maxWords; } There are two changes in the preceding code: ➤ read more..

  • Page - 190

    154 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION A custom attribute is one approach to providing validation logic for models. As you can see, an attribute is easily reusable across a number of different model classes. In Chapter 8, you’ll add client- side validation capabilities for the MaxWordsAttribute . IValidatableObject A self-validating read more..

  • Page - 191

    Display and Edit Annotations ❘ 155 At this point I’ve covered everything you need to know about validation annotations, but additional annotations in the MVC framework infl uence how the run time displays and edits a model. I alluded to these annotations earlier in the chapter when I talked about a “friendly display name,” and now you’ve read more..

  • Page - 192

    156 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION With the attribute in place, your view renders as shown in Figure 6-10. FIGURE 6-10 In addition to the name, the Display attribute enables you to control the order in which properties will appear in the UI. For example, to control the placement of the LastName and FirstName edi- tors, you read more..

  • Page - 193

    Display and Edit Annotations ❘ 157 the runtime to apply to the property value. In the following code you format the Total property of a model as a currency value: [DisplayFormat(ApplyFormatInEditMode=true, DataFormatString="{0:c}")] public decimal Total { get; set; } The ApplyFormatInEditMode parameter is false by default, so if you want the Total read more..

  • Page - 194

    158 ❘ CHAPTER 6 DATA ANNOTATIONS AND VALIDATION FIGURE 6-12 Other data types include Currency , Date , Time , and MultilineText . UIHint The UIHint attribute gives the ASP.NET MVC runtime the name of a template to use when render- ing output with the templated helpers (such as DisplayFor and EditorFor ). You can defi ne your own template helpers read more..

  • Page - 195

    Membership, Authorization, and Security —by Jon Galloway WHAT’S IN THIS CHAPTER? ➤ Requiring login with the Authorize Attribute ➤ Requiring role membership using the Authorize Attribute ➤ Using security vectors in a web application ➤ Coding defensively WROX.COM CODE DOWNLOADS FOR THIS CHAPTER All code for this chapter is provided via NuGet, as described in read more..

  • Page - 196

    160 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY authors, read these books, too—a lot of them—and we’re quite aware that we’re lucky to have you as a reader, and we’re not about to abuse that trust. In short, we really want this chapter to be infor- mative because security is very important! ASP.NET WEB FORMS DEVELOPERS: read more..

  • Page - 197

    Security: Not fun, but incredibly important ❘ 161 Here are some practical examples: ➤ Any time you render data that originated as user input, encode it. The most common prac- tice is to HTML encode it, though you sometimes need to HTML attribute encode it if it’s displayed as an attribute value, or JavaScript encode it if it’s being used in a JavaScript read more..

  • Page - 198

    162 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY This chapter starts with a look at how to use the security features in ASP.NET MVC to perform application functions such as authorization, and then moves on to look at how to handle common security threats. Remember that it’s all part of the same continuum, though. You want to read more..

  • Page - 199

    public ActionResult Index() { var albums = GetAlbums(); return View(albums); } public ActionResult Buy(int id) { var album = GetAlbums().Single(a => a.AlbumId == id); //Charge the user and ship the album!!! return View(album); } read more..

  • Page - 200

    164 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY FIGURE 7-1 When you click the Buy link, however, you are required to log in (see Figure 7-2). FIGURE 7-2 read more..

  • Page - 201

    Using the Authorize Attribute to Require Login ❘ 165 Because you don’t have an account yet, you’ll need to click the Register link, which displays a standard account signup page (see Figure 7-3). FIGURE 7-3 Notice that the standard AccountController registration doesn’t track the referrer when you create a new account, so after creating a new read more..

  • Page - 202

    166 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY USING URL AUTHORIZATION A common means of securing an application with Web Forms is to use URL autho- rization. For example, if you have an admin section and you want to restrict it to users who are in the Admins role, you might place all your admin pages in an admin folder and read more..

  • Page - 203

    Using the Authorize Attribute to Require Login ❘ 167 How AuthorizeAttribute Works with Forms Authentication and the AccountController What’s going on behind the scenes with this authentication scenario? Clearly, we didn’t write any code (controllers or views) to handle the Log On and Register URLs, so where did it come from? The ASP.NET MVC template read more..

  • Page - 204

    168 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY BEHIND THE SCENES IN THE 401 TO 302 REDIRECTION PROCESS In ASP.NET MVC 5, the 401 to 302 redirection process is handled by OWIN (Open Web Interface for .NET) middleware components. Cookie-based authentica- tion is handled by the CookieAuthenticationHandler (found in the Microsoft. Owin.Cookies read more..

  • Page - 205

    Using the Authorize Attribute to Require Login ❘ 169 It’s nice that the AccountController —and its associated views—are all provided in the ASP.NET MVC with the individual user accounts authentication template. In simple cases, adding authoriza- tion doesn’t require any additional code or confi guration. Equally nice, though, is that you can change read more..

  • Page - 206

    170 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY To enable Windows authentication on Windows Server: a. In the Server Manager, select Web Server (IIS) and click Add Role Services. b. Navigate to Web Server ➪ Security and make sure the Windows authentication node is checked. 4. In the Actions pane, click Enable to use Windows authentication. read more..

  • Page - 207

    Using the Authorize Attribute to Require Login ❘ 171 To register the AuthorizeAttribute as a global fi lter, add it to the global fi lters collection in the RegisterGlobalFilters method, located in \App_Start\FilterConfig.cs : public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new System.Web.Mvc.AuthorizeAttribute()); read more..

  • Page - 208

    172 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY This way, even if you register the AuthorizeAttribute as a global fi lter, users can access the login actions. Although AllowAnonymous solves this specifi c problem, it only works with the standard AuthorizeAttribute ; it won’t necessarily work with custom authorization fi lters. If read more..

  • Page - 209

    Using AuthorizeAttribute to Require Role Membership ❘ 173 MANAGING PERMISSIONS: USERS, ROLES, AND CLAIMS Managing your permissions based on roles instead of users is generally considered a better idea, for several reasons: ➤ Users can come and go, and a specifi c user is likely to require (or lose) permis- sions over time. ➤ Managing role membership is read more..

  • Page - 210

    174 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY transition between the StoreController , CheckoutController , and StoreManagerController . This interaction requires several controllers and a backing database, so downloading the completed application code is simpler than installing a NuGet package and walking through a long list of con- fi guration steps. read more..

  • Page - 211

    External Login via OAuth and OpenID ❘ 175 Additionally, ASP.NET Identity’s data storage is built on top of the UserStore and RoleStore abstractions. You can implement your own UserStore and / or RoleStore to persist your data in any way you’d like, including Azure Table Storage, custom fi le formats, web service calls, etc. This tutorial read more..

  • Page - 212

    176 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY Setting up your site to support OAuth and OpenID has been diffi cult to implement in the past for two reasons: These protocols are complex, and many top providers implement them a little differ- ently. MVC’s project templates greatly simplify this by including built-in support for OAuth read more..

  • Page - 213

    External Login via OAuth and OpenID ❘ 177 application, all authentication providers in Startup.Auth.cs are commented out and will appear as follows: public partial class Startup { // For more information on configuring authentication, // please visit public void ConfigureAuth(IAppBuilder read more..

  • Page - 214

    178 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY client id as consumer key, app id, and so on. Fortunately, these middleware methods for each provider use parameter names that match the provider’s terms and documentation. Confi guring OpenID Providers Confi guring an OpenID provider is relatively simple, because no registration is required and read more..

  • Page - 215

    External Login via OAuth and OpenID ❘ 179 FIGURE 7-6 FIGURE 7-7 read more..

  • Page - 216

    180 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY After clicking Accept, you are redirected back to the ASP.NET MVC site to complete the registra- tion process (see Figure 7-8). FIGURE 7-8 After clicking the Register button, you are redirected to the home page as an authenticated user. At the time of this writing, the new ASP.NET Identity read more..

  • Page - 217

    External Login via OAuth and OpenID ❘ 181 (when using Individual Account for authentication) includes support for three specifi c OAuth providers (Microsoft, Facebook, and Twitter) as well as a generic OAuth implementation. NOTE Note that unlike the MVC 4 implementation, which relied on the DotNetOpenAuth NuGet package, the MVC 5 OAuth middleware does read more..

  • Page - 218

    182 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY Trusted External Login Providers Supporting only providers whose security you trust, which generally means sticking with well- known providers, is important for a couple reasons: ➤ When you are redirecting your users to external sites, you want to make sure that these sites are not malicious or poorly secured read more..

  • Page - 219

    Understanding the Security Vectors in a Web Application ❘ 183 However, if you’ll remember, the chapter began with dire warnings about how your applications need security features that do nothing but prevent misuse. When your web application is exposed to public users—especially the enormous, anonymous public Internet—it is vulnerable to a read more..

  • Page - 220

    184 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY the form will display on the site, and second, they know that encoding URLs is tricky, and develop- ers usually forego checking these properly because they are part of an anchor tag anyway. One thing to always remember (if we haven’t overstated it already) is that the Black Hats read more..

  • Page - 221

    Understanding the Security Vectors in a Web Application ❘ 185 This entry closes off the anchor tag that is not protected and then forces the site to load an IFRAME, as shown in Figure 7-12. FIGURE 7-12 This would be pretty silly if you were out to hack a site, because it would tip off the site’s admin- istrator and a fi x read more..

  • Page - 222

    186 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY Active Injection Active XSS injection involves a user sending in malicious information that is immediately shown on the page and is not stored in the database. The reason it’s called active is that it involves the user’s participation directly in the attack—it doesn’t sit and wait read more..

  • Page - 223

    Understanding the Security Vectors in a Web Application ❘ 187 show this vulnerability (from the people at Acunetix, who built this site intentionally to show how active injection can work), and loading the preceding term into their search form renders what’s shown in Figure 7-15. FIGURE 7-15 We could have spent a little more time with the read more..

  • Page - 224

    188 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY If you get only one thing from this chapter, please let it be this: Every bit of output on your pages should be HTML encoded or HTML attribute encoded. I said this at the beginning of the chapter, but I want to say it again: Html.Encode is your best read more..

  • Page - 225

    Understanding the Security Vectors in a Web Application ❘ 189 To properly sanitize this link, you need to be sure to encode the URL that you’re expecting. This replaces reserved characters in the URL with other characters (" " with %20 , for example). You might also have a situation in which you’re passing a value through read more..

  • Page - 226

    190 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY @section scripts { @if(ViewBag.UserName != null) { <script type="text/javascript"> $(function () { var msg = 'Welcome, @ViewBag.UserName!'; $("#welcome-message").html(msg).hide().show('slow'); }); read more..

  • Page - 227

    Understanding the Security Vectors in a Web Application ❘ 191 Using AntiXSS as the Default Encoder for ASP.NET The AntiXSS library can add an additional level of security to your ASP.NET applications. There are a few important differences in how it works compared with the ASP.NET and MVC encoding functions, but the most important are as follows: read more..

  • Page - 228

    192 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY <div class="content-wrapper"> <hgroup class="title"> <h1>@ViewBag.Title.</h1> <h2 id="welcome-message"></h2> </hgroup> read more..

  • Page - 229

    Understanding the Security Vectors in a Web Application ❘ 193 NOTE Note that, although using the AntiXSS encoder that ships with ASP.NET is easy, fi nding cases for which the whitelist approach is preferable to the stan- dard blacklist approach is a little diffi cult. There are only so many approaches to XSS, and we haven’t seen a read more..

  • Page - 230

    194 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY Now, suppose that your site allows limited whitelist HTML (a list of acceptable tags or characters that might otherwise get encoded) to be entered as part of a comment system (maybe you wrote a forums app or a blog) — most of the HTML is stripped or sanitized, but read more..

  • Page - 231

    Understanding the Security Vectors in a Web Application ❘ 195 actually carry out their transfer requests, and one of them offers some seriously low-hanging fruit— the transfer is identifi ed in the URL: ↵ toaccountnumber=23234554333&from=checking Granted, this might strike you as extremely read more..

  • Page - 232

    196 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY they land on the site, a hidden iFRAME or bit of script auto-submits a form (using HTTP POST) off to a bank, trying to make a transfer. If you’re a Widely Used Bank customer and have just been there, this attack will work. Revisiting the previous forum post social engineering read more..

  • Page - 233

    Understanding the Security Vectors in a Web Application ❘ 197 auto-register (and then spam) users to your site. We will look at ways to limit this kind of thing later in the chapter. Idempotent GETs Idempotent is a big word, for sure—but it’s a simple concept. If an operation is idempotent, it can be executed multiple times without read more..

  • Page - 234

    198 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY This section discusses cookie stealing, what it means to you, and how to prevent it. Cookie-Stealing Threat Summary Websites use cookies to store information between page requests or browsing sessions. Some of this information is pretty tame—things like site preferences and history. Other read more..

  • Page - 235

    Understanding the Security Vectors in a Web Application ❘ 199 The problem in this case was a custom whitelist approach to XSS prevention. The attacker, in this case, exploited a hole in the homegrown HTML sanitizer: Through clever construction, the malformed URL just manages to squeak past the sanitizer. The fi nal rendered code, when read more..

  • Page - 236

    200 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY Threat: Over-Posting ASP.NET MVC Model Binding is a powerful feature that greatly simplifi es the process handling user input by automatically mapping the input to your model properties based on naming conven- tions. However, this presents another attack vector, which can allow your attacker an read more..

  • Page - 237

    Understanding the Security Vectors in a Web Application ❘ 201 administrative user record for the “rails” us er by adding that hidden fi eld to the form on which he had created the public key: <input type=hidden value=USER_ID_OF_TARGET_ACCOUNT name=public_key[user_id]> He inserted the User ID of the target account into the value attribute of that form fi read more..

  • Page - 238

    202 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY A second alternative is to use one of the overloads on UpdateModel or TryUpdateModel that accepts a bind list, like the following: UpdateModel(review, "Review", new string[] { "Name", "Comment" }); Still another—and arguably, the best—way to deal with over-posting is to avoid read more..

  • Page - 239

    Understanding the Security Vectors in a Web Application ❘ 203 AuthorizeAttribute redirects unauthorized users to the /Account/LogOn view. This redirect to / Account/LogOn includes a returnUrl query string parameter so that the users can be returned to the originally requested URL after they have successfully logged in. In Figure 7-18, you can see read more..

  • Page - 240

    204 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY First, an attacker sends a link to the login page on NerdDinner that includes a redirect to their forged page: Account/LogOn Note that the return URL points to a hypothetical site, which is missing an “n” from the word read more..

  • Page - 241

    Understanding the Security Vectors in a Web Application ❘ 205 FIGURE 7-20 When you retype your username and password, the forged login page saves the information and sends you back to the legitimate site. At this point, the site has already authenticated us, so the forged login page can redirect directly to that read more..

  • Page - 242

    206 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY if (ModelState.IsValid) { if (MembershipService.ValidateUser(model.UserName, model.Password)) { FormsService.SignIn(model.UserName, model.RememberMe); if (!String.IsNullOrEmpty(returnUrl)) { return read more..

  • Page - 243

    Proper Error Reporting and the Stack Trace ❘ 207 Taking Additional Actions When an Open Redirect Attempt Is Detected The AccountController ’s open redirect check prevents the attack, but doesn’t notify you or the user that it occurred. You may want to take additional actions when an open redirect is detected. For instance, you might want to read more..

  • Page - 244

    208 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY Detailed error messages can expose information about how your application works. Hackers can exploit this by forcing your site to fail—perhaps sending in bad information to a controller using a malformed URL or tweaking the query string to send in a string when an integer is required. Temporarily read more..

  • Page - 245

    Security Recap and Helpful Resources ❘ 209 <customErrors defaultRedirect="GenericError.htm" mode="RemoteOnly" xdt:Transform="Replace"> <error statusCode="500" redirect="InternalError.htm"/> </customErrors> </system.web> Using Retail Deployment Confi guration in Production Rather than fi ddle read more..

  • Page - 246

    210 ❘ CHAPTER 7 MEMBERSHIP, AUTHORIZATION, AND SECURITY TABLE 7-1: ASP.NET Security THREAT SOLUTIONS Complacency Educate yourself. Assume your applications will be hacked. Remember that protecting user data is important. Cross-Site Scripting (XSS) HTML encode all content. Encode attributes. Remember JavaScript encoding. Use AntiXSS. Cross-Site Request Forgery (CSRF) Token verifi cation. read more..

  • Page - 247

    Summary ❘ 211 RESOURCE URL Microsoft Information Security Team (makers of AntiXSS and CAT.NET) Open Web Application Security Project (OWASP) SUMMARY We started the chapter off this way, and ending it this way is appropriate: ASP.NET MVC gives you a lot of control and removes a lot of the abstraction that some read more..

  • Page - 248

    read more..

  • Page - 249

    Ajax —by K. Scott Allen and Jon Galloway WHAT’S IN THIS CHAPTER? ➤ Understanding jQuery ➤ Using Ajax helpers ➤ Understanding client validation ➤ Using jQuery plugins ➤ Improving Ajax performance WROX.COM CODE DOWNLOADS FOR THIS CHAPTER You can fi nd the code downloads for this chapter at proaspnetmvc5 on the Download read more..

  • Page - 250

    214 ❘ CHAPTER 8 AJAX responsive does require some asynchronous communication now and then, but the appearance of responsiveness can also come from subtle animations and color changes. If you can visually encourage your users to make the right choices inside your application, they’ll love you and come back for more. ASP.NET MVC 5 is a read more..

  • Page - 251

    jQuery ❘ 215 $(function () { $("#album-list img").mouseover(function () { $(this).animate({ height: '+=25', width: '+=25' }) .animate({ height: '-=25', width: '-=25' }); }); }); The fi rst line of code invokes the jQuery function ($) and passes an anonymous JavaScript function as the fi rst parameter. read more..

  • Page - 252

    216 ❘ CHAPTER 8 AJAX $(function () { $("#album-list img").mouseover(function () { $(this).animate({ height: '+=25', width: '+=25' }) .animate({ height: '-=25', width: '-=25' }); }); }); In the preceding example, the code animates an element during the mouseover event. The element the code animates is read more..

  • Page - 253

    jQuery ❘ 217 The last line in the table demonstrates how jQuery supports the same pseudo-classes you might be familiar with from CSS. Using a pseudo-class allows you to select even or odd numbered elements, visited links, and more. For a full list of available CSS selectors, visit selectors/ . jQuery Events Another read more..

  • Page - 254

    218 ❘ CHAPTER 8 AJAX ➤ Shortcuts are available in jQuery for many common operations. Setting up effects for mouseover and mouseout is a common operation, and so is toggling the presence of a style class. You could rewrite the last snippet using some jQuery shortcuts and the code would morph into the following: $("a").hover(function () { read more..

  • Page - 255

    jQuery ❘ 219 ASP.NET MVC 5 takes an unobtrusive approach to JavaScript. Instead of emitting JavaScript code into a view to enable features such as client-side validation, the framework sprinkles metadata into HTML attributes. Using jQuery, the framework can fi nd and interpret the metadata, and then attach behaviors to elements, all using external script read more..

  • Page - 256

    220 ❘ CHAPTER 8 AJAX Note that ASP.NET MVC’s Razor view engine will resolve the ~ operator to the root of the current website, even when the ~ appears in an src attribute. Also note that specifying the type attribute as text/javascript isn’t needed in HTML 5. Although a simple script reference (as shown earlier) works, it’s read more..

  • Page - 257

    jQuery ❘ 221 Custom Scripts When you write your own custom JavaScript code, you can add your code into new fi les in the Scripts directory (unless you want to write intrusive JavaScript; then go ahead and embed script code directly in your view, but you lose 25 karma points when you do this). Because the Scripts directory in a new read more..

  • Page - 258

    222 ❘ CHAPTER 8 AJAX If the script contains functionality the entire application will use, you can place the script tag in the _Layout view, after the bundle reference for jQuery. In this example, you need to use the script only on the front page of the application, so it needs to be added inside the Index view of the read more..

  • Page - 259

    jQuery ❘ 223 <ul class="row list-unstyled" id="album-list"> @foreach (var album in Model) { <li class="col-lg-2 col-md-2 col-sm-2 col-xs-4 container"> <a href="@Url.Action("Details", "Store", new { id = album.AlbumId })"> <img alt="@album.Title" src="@Url.Content( read more..

  • Page - 260

    224 ❘ CHAPTER 8 AJAX That looks like quite a list! However, it’s really only six libraries. To narrow down the list, we’ll start by discussing the things that aren’t really JavaScript libraries. _references.js is just a list of JavaScript libraries in your project, written out using triple-slash (///) comments. Visual Studio uses read more..

  • Page - 261

    Ajax Helpers ❘ 225 Respond.js is a tiny JavaScript library, included because it’s required by Bootstrap. It’s what’s known as a polyfi ll: a JavaScript library that adds support for newer browser standards to older browsers. In the case of Respond.js , that missing standard is min-width and max-width CSS3 media query support for read more..

  • Page - 262

    226 ❘ CHAPTER 8 AJAX FIGURE 8-3 You can either add a script reference to the application’s _Layout view or just in views that will be using the Ajax helpers. Unless you’re making a lot of Ajax requests throughout your site, I recom- mend just adding script references to individual views. This example shows how to add an Ajax read more..

  • Page - 263

    Ajax Helpers ❘ 227 for the MVC Music Store. When users click the link, you don’t want them to navigate to a new page, but you want the existing page to automatically display the details of a heavily discounted album. To implement this behavior, you can add the following code into the Views/Home/Index.cshtml view, just below the existing read more..

  • Page - 264

    228 ❘ CHAPTER 8 AJAX RANDOM ORDERING IN A LINQ QUERY The above code is selecting a random album using a neat trick suggested by Jon Skeet on StackOverfl ow. Because new Guids are generated in semi-random order, ordering by NewGuid essentially shuffl es them. The above example does the shuf- fl ing in the database; to move that work to read more..

  • Page - 265

    Ajax Helpers ❘ 229 Now when the user clicks the link, an asynchronous request is sent to the DailyDeal action of the HomeController. A fter the action returns the HTML from a rendered view, the script behind the s cenes takes the HTML and replaces the existing dailydeal element in the DOM. Before the user clicks, the bottom of the homepage would read more..

  • Page - 266

    230 ❘ CHAPTER 8 AJAX HTML 5 Attributes If you look at the rendered markup for the action link, you’ll fi nd the following: <div id="dailydeal"> <a class="btn btn-primary" data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#dailydeal" read more..

  • Page - 267

    Ajax Helpers ❘ 231 <div class="panel-body"> @using (Ajax.BeginForm("ArtistSearch", "Home", new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "GET", OnFailure = read more..

  • Page - 268

    232 ❘ CHAPTER 8 AJAX public ActionResult ArtistSearch(string q) { var artists = GetArtists(q); return PartialView(artists); } private List<Artist> GetArtists(string searchString) { return storeDB.Artists .Where(a => a.Name.Contains(searchString)) .ToList(); } The partial view takes the model and builds the list. This view is named read more..

  • Page - 269

    Client Validation ❘ 233 NOTE To view the preceding example, run the MvcMusicStore.C08.AjaxForm example. We’ll return to this search form later in the chapter to add some additional features. For now, turn your attention to another built-in Ajax feature of the ASP.NET MVC framework—the support for client-side validation. CLIENT VALIDATION Client read more..

  • Page - 270

    234 ❘ CHAPTER 8 AJAX This means the bundle will include both jquery.validate.js and jquery.validate.unobtru- sive.js —everything you need for unobtrusive validation based on jQuery Validation. The easiest way to include this script reference is to make sure you select the Reference script libraries checkbox when you scaffold a new controller, as shown read more..

  • Page - 271

    Client Validation ❘ 235 If you want to turn off either feature throughout the application, you can change either setting to false. In addition, you can also control these settings on a view-by-view basis. The HTML helpers EnableClientValidation and EnableUnobtrusiveJavascript override the confi guration settings inside a specifi c view. The read more..

  • Page - 272

    236 ❘ CHAPTER 8 AJAX Once again, you see data dash attributes. It’s the responsibility of the jquery.validate.unobtru- sive script to fi nd elements with this metadata (starting with data-val="true" ) and to interface with the jQuery Validation plugin to enforce the validation rules expressed inside the metadata. jQuery Validation can read more..

  • Page - 273

    Client Validation ❘ 237 To support client-side validation, you need your attribute to implement an interface, as discussed in the next section. IClientValidatable The IClientValidatable interface defi nes a single method: GetClientValidationRules . When the MVC framework fi nds a validation object with this interface present, it invokes GetClientValidationRules read more..

  • Page - 274

    238 ❘ CHAPTER 8 AJAX If you think about the scenario, there are a few pieces of information you would need on the client to run the validation: ➤ What error message to display if the validation fails ➤ How many words are allowed ➤ An identifi er for a piece of JavaScript code that can count the words This information is exactly what the read more..

  • Page - 275

    Client Validation ❘ 239 MusicScripts.js would require the jqueryval bundle. Instead, you’ll create a new script fi le called CustomValidators.js . NOTE In this chapter, we’ve decided that jQueryUI is common enough to our application that we’re requiring it in MusicScripts.js . However, we’re only going to need validation on views with read more..

  • Page - 276

    240 ❘ CHAPTER 8 AJAX The fi rst parameter is the name of the adapter, and must match the ValidationProperty value you set on the server-side rule. The second parameter is the name of the single parameter to retrieve from metadata. Notice you don’t use the data- prefi x on the parameter name; it matches the name of the parameter you read more..

  • Page - 277

    Beyond Helpers ❘ 241 FIGURE 8-8 NOTE To see this custom validation example, run the MvcMusicStore.C08. CustomClientValidation sample and browse to /StoreManager/Create . Although the ASP.NET MVC Ajax helpers provide a great deal of functionality, there is an entire eco- system of jQuery extensions that go much further. The next section explores read more..

  • Page - 278

    242 ❘ CHAPTER 8 AJAX jQuery UI jQuery UI is a jQuery plugin that includes both effects and widgets. Like all plugins it integrates tightly with jQuery and extends the jQuery API. As an example, let’s return to the fi rst bit of code in this chapter—the code to animate album items on the front page of the store: $(function () read more..

  • Page - 279

    Beyond Helpers ❘ 243 You can fi nd out what options are available (and their default values) by reading the plugin documentation on . Additional effects in jQuery UI include explode, fade, shake, and pulsate. OPTIONS, OPTIONS EVERYWHERE The options parameter is pervasive throughout jQuery and jQuery plugins. Instead of having a method that read more..

  • Page - 280

    244 ❘ CHAPTER 8 AJAX Adding the Behavior First, remember the artist search scenario you worked on in the section “Ajax Forms” earlier in the chapter? Now, you want the search input to display a list of possible artists when the user starts typing inside the input. You’ll need to fi nd the input element from JavaScript and attach read more..

  • Page - 281

    Beyond Helpers ❘ 245 list, the widget places the value of the selected item into the associated input. If you don’t provide a label , or don’t provide a value , autocomplete will use whichever property is available as both the value and the label. To return the proper JSON, you implement QuickSearch with the following code: public read more..

  • Page - 282

    246 ❘ CHAPTER 8 AJAX ➤ However, a chance exists that a malicious user can gain access to the JSON payload through a process known as JSON hijacking. You do not want to return sensitive information using JSON in a GET request. For more details, see Phil’s post at archive/2009/06/25/json-hijacking.aspx . JSON is not only fantastically easy to read more..

  • Page - 283

    Beyond Helpers ❘ 247 Adding Templates You’ll add mustache.js to your project as you would expect: by installing the mustache.js NuGet package. You can do that using Install-Package mustache.js or via the Manage NuGet Packages dialog as shown in Figure 8-10. FIGURE 8-10 When NuGet is fi nished adding the package to the project, you should read more..

  • Page - 284

    248 ❘ CHAPTER 8 AJAX })) { <input type="text" name="q" data-autocomplete-source="@Url.Action("QuickSearch", "Home")" /> <input type="submit" value="search" /> <img id="ajax-loader" src="@Url.Content("~/Content/Images/ajax-loader.gif")" read more..

  • Page - 285

    Beyond Helpers ❘ 249 public ActionResult ArtistSearch(string q) { var artists = GetArtists(q); return Json(artists, JsonRequestBehavior.AllowGet); } Now you’ll need to change the script to expect JSON instead of HTML. jQuery provides a method named getJSON that you can use to retrieve the data: $("#artistSearch").submit(function (event) { read more..

  • Page - 286

    250 ❘ CHAPTER 8 AJAX <ul> {{#artists}} <li>{{Name}}</li> {{/artists}} </ul> </script> <div id="searchresults"></div> To use the template, you need to select it inside the getJSON callback and tell Mustache to render read more..

  • Page - 287

    Beyond Helpers ❘ 251 complete: function () { $("#ajax-loader").hide(); }, error: searchFailed, success: function (data) { var html = Mustache.to_html($("#artistTemplate").html(), read more..

  • Page - 288

    252 ❘ CHAPTER 8 AJAX <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <h4 class="modal-title" id="myModalLabel"> read more..

  • Page - 289

    Improving Ajax Performance ❘ 253 NOTE Bootstrap is discussed in more detail in Chapters 1 and 16. It’s a very versatile, powerful platform, and it’s very much worth your time to get familiar with the documentation at . IMPROVING AJAX PERFORMANCE When you start sending large amounts of script code to the read more..

  • Page - 290

    254 ❘ CHAPTER 8 AJAX inside the <head> tag at the top of the page is that when the browser comes across a script tag, it blocks other downloads until after it retrieves the entire script. This blocking behavior can make a page load slowly. Moving all your script tags to the bottom of a page (just before the closing body read more..

  • Page - 291

    Summary ❘ 255 After you have bundles confi gured, you can render the bundles with Scripts and Styles helper classes. The following code outputs the jQuery bundle and the default application style sheet: @Scripts.Render("~/bundles/jquery") @Styles.Render("~/Content/css") The parameter you pass to the Render methods is the virtual path used to create read more..

  • Page - 292

    read more..

  • Page - 293

    Routing —by Phil Haack and David Matson WHAT’S IN THIS CHAPTER? ➤ Understanding URLs ➤ Introduction to Routing ➤ A peek under the Routing hood ➤ A look at advanced Routing ➤ Routing extensibility and magic ➤ Using Routing with Web Forms When it comes to source code, software developers are notorious for fi xating on little details to read more..

  • Page - 294

    258 ❘ CHAPTER 9 ROUTING heavy use of to map URLs to method calls. The chapter covers both traditional routing as well as the new attribute routing introduced in ASP.NET MVC 5. The chapter fi rst covers how MVC uses Routing and then takes a peek under the hood at Routing as a standalone feature. UNIFORM RESOURCE LOCATORS Usability read more..

  • Page - 295

    Introduction to Routing ❘ 259 Arguably this is all just semantics, and most people will get your meaning regardless of which name you use. However, this discussion might be useful to you as you learn MVC because it acts as a reminder that a URL doesn’t necessarily mean a physical location of a static fi le on a web read more..

  • Page - 296

    260 ❘ CHAPTER 9 ROUTING The key difference is that URL rewriting is focused on mapping one URL to another URL. For example, URL rewriting is often used for mapping old sets of URLs to a new set of URLs. Contrast that to Routing, which is focused on mapping a URL to a resource. You might say that Routing embodies a resource-centric read more..

  • Page - 297

    Introduction to Routing ❘ 261 In the following sections, we’ll start with an extremely simple route and build up from there. Route URLs After you create a new ASP.NET MVC Web Application project, take a quick look at the code in Global.asax.cs . You’ll notice that the Application_Start method contains a call to the RegisterRoutes method. read more..

  • Page - 298

    262 ❘ CHAPTER 9 ROUTING Route Values The static routes you saw earlier are great for the simplest routes, but not every URL is static. For example, if your action shows the details for a person record, you might want to include the record ID in your URL. That’s solved by adding a route parameter: [Route("person/{id}")] public ActionResult read more..

  • Page - 299

    Introduction to Routing ❘ 263 via the RequestContext ), using the route parameter names as the keys and the corresponding sub- sections of the URL (based on position) as the values. When an attribute route matches and an action method runs, the route parameters from the route are used by model binding to populate values for any method read more..

  • Page - 300

    264 ❘ CHAPTER 9 ROUTING We’ve removed all the route attributes above each method and replaced them with one attribute on the controller class. When you defi ne a route on the controller class, you can use a special route parameter named action , and it serves as a placeholder for any action name. It has the same effect as your read more..

  • Page - 301

    Introduction to Routing ❘ 265 public ActionResult About() { return View(); } public ActionResult Contact() { return View(); } } Now, all your route attributes can omit home/ because the prefi x provides that automatically. The prefi x is just a default, and you can read more..

  • Page - 302

    266 ❘ CHAPTER 9 ROUTING For this route, think about what happens when a request comes in for the URL /person/bob . What’s the value of id ? Well, that’s a trick question: The answer depends on which id you’re talking about, the route parameter or the action method parameter. As you saw earlier, a route parameter in a route will read more..

  • Page - 303

    Introduction to Routing ❘ 267 Note the key difference here: instead of defi ning the route parameter as just {id} , you’ve now defi ned it as {id:int} . Putting a constraint in the route template like this is called an inline constraint, and a number of them are available, as Table 9-2 shows. TABLE 9-2: Inline Constraints NAME read more..

  • Page - 304

    268 ❘ CHAPTER 9 ROUTING matching requests. Providing default values for a route parameter is also possible. For example, sup- pose that you have an Index action method that does not have a parameter: [Route("home/{action}")] public class HomeController : Controller { public ActionResult Index() { return View(); read more..

  • Page - 305

    Introduction to Routing ❘ 269 [Route("details/{id}")] public ActionResult Details(int id) { // Show the details for the contact with this id return View(); } [Route("update/{id}")] public ActionResult Update(int id) { // Display a form to update the read more..

  • Page - 306

    270 ❘ CHAPTER 9 ROUTING You can provide multiple default or optional values. The following snippet demonstrates providing a default value for the {action} parameter, as well: [Route("{action=Index}/{id?}")] This example supplies a default value for the {action} parameter within the URL. Typically the URL pattern of contacts/{action} requires a two-segment URL read more..

  • Page - 307

    Introduction to Routing ❘ 271 parameter also has a default value defi ned (including an optional parameter, which uses the default value UrlParameter.Optional ). In this example, if you have a default value for {action} you should also provide a default value for {id} (or make it optional). Routing interprets default values slightly differently read more..

  • Page - 308

    272 ❘ CHAPTER 9 ROUTING Unfortunately, this exact approach doesn’t combine well with attribute rout- ing. (Attribute routing needs to fi nd controller classes and action methods to locate their route attributes, and that process is only designed to work when the MapMvcAttributeRoutes method is being called within an ASP.NET site.) To work read more..

  • Page - 309

    Introduction to Routing ❘ 273 You can fi x this problem by changing your simple route to include these required parameters: routes.MapRoute("simple", "{controller}/{action}"); Now, if you make a request to a URL such as /home/index , MVC sees it as a request for a {controller} named home and an {action} named index . By read more..

  • Page - 310

    274 ❘ CHAPTER 9 ROUTING A request for /albums/display/123 causes MVC to instantiate this class and call the Display method, passing in 123 for the id . In the previous example with the route URL {controller}/{action}/{id} , each segment contains a route parameter that takes up the entire segment. This doesn’t have to be the case. Route URLs read more..

  • Page - 311

    Introduction to Routing ❘ 275 { //Do something return View(); } } Naturally, you might want to call this method via the URL: /albums/list However, given the route URL defi ned in the previous snippet, {controller}/{action}/{id} , this won’t work because this route matches only URLs containing three read more..

  • Page - 312

    276 ❘ CHAPTER 9 ROUTING The earlier example supplies a default value for the {action} parameter within the URL via the Defaults dictionary property of the Route class. Typically the URL pattern of {controller}/ {action} would require a two-segment URL in order to be a match. But by supplying a default value for the second parameter, this route read more..

  • Page - 313

    Introduction to Routing ❘ 277 comes into play when generating URLs, which is covered later in the section “Inside Routing: How Routes Generate URLs.” Route Constraints Sometimes you need more control over your URLs than specifying the number of path segments. For example, take a look at the following two URLs: ➤ ➤ read more..

  • Page - 314

    278 ❘ CHAPTER 9 ROUTING NOTE Attribute routing has the opposite behavior for regular expression match- ing. Traditional routing always does an exact match, whereas the attribute rout- ing regex inline constraint supports partial matches. The traditional routing constraint year = @"\d{4}" is the equivalent to {year:regex(^\d{4}$)} as an read more..

  • Page - 315

    Introduction to Routing ❘ 279 route and an attribute route, the fi rst route registered wins. In practice, we recommend putting the MapMvcAttributeRoutes call fi rst. Attribute routes are usually more specifi c, and having attribute routes come fi rst allows them to take precedence over traditional routes, which are usually more generic. Suppose read more..

  • Page - 316

    280 ❘ CHAPTER 9 ROUTING Choosing Attribute Routes or Traditional Routes Should you use attribute routes or traditional routes? Either option is reasonable, but here are some suggestions on when to use each one. Consider choosing traditional routes when: ➤ You want centralized confi guration of all your routes. ➤ You use custom constraint objects. ➤ You read more..

  • Page - 317

    Introduction to Routing ❘ 281 To generate a hyperlink to each route from within a view, you write the following code: @Html.RouteLink("to Test", new {controller="section", action="Index", id=123}) @Html.RouteLink("to Default", new {controller="Home", action="Index", id=123}) Notice that these two method calls don’t specify which route to use to read more..

  • Page - 318

    282 ❘ CHAPTER 9 ROUTING is really leaving it to chance, which is not something that sits well with the obsessive-compulsive, control-freak developer. When generating a URL, you generally know exactly which route you want to link to, so you might as well give it a name and use it. If you have a need to use non-named routes and read more..

  • Page - 319

    Introduction to Routing ❘ 283 Area Route Confl icts If you have two controllers with the same name, one within an area and one in the root of your application, you might run into an exception with a rather verbose error message when a request matches the route without a namespace: Multiple types were found that match the controller named read more..

  • Page - 320

    284 ❘ CHAPTER 9 ROUTING By default, all attribute routes for this class use the area name as the route prefi x. So the preceding route is for URLs like /admin/users/index . If you would rather have a different route prefi x, you can use the optional AreaPrefix property: [RouteArea("admin", AreaPrefix = "manage")] read more..

  • Page - 321

    Introduction to Routing ❘ 285 TABLE 9-4: Catch-All Route Requests URL PARAMETER VALUE /query/select/a/b/c extrastuff = "a/b/c" /query/select/a/b/c/ extrastuff = "a/b/c/" /query/select/ extrastuff = null (Route still matches. The catch-all just catches the null string in this case.) Multiple Route Parameters in a Segment As mentioned earlier, a route URL may have read more..

  • Page - 322

    286 ❘ CHAPTER 9 ROUTING StopRoutingHandler and IgnoreRoute By default, Routing ignores requests that map to physical fi les on disk. That’s why requests for fi les such as CSS, JPG, and JS fi les are ignored by Routing and handled in the normal manner. However, in some situations, there are requests that don’t map to a fi le read more..

  • Page - 323

    Introduction to Routing ❘ 287 its position in the list. All this used to make for frustrating debugging sessions—that is, before Phil Haack wrote the Route Debugger. When the Route Debugger is enabled it replaces all of your routes’ route handlers with a DebugRouteHandler . This route handler traps all incoming requests and queries every route in read more..

  • Page - 324

    288 ❘ CHAPTER 9 ROUTING NOTE I provided the full source for the Route Debugger, so you can modify it to output any other data that you think is relevant. For example, Stephen Walther used the Route Debugger as the basis of a Route Debugger Controller. Because it hooks in at the Controller level, it’s only able to handle read more..

  • Page - 325

    Inside Routing: How Routes Generate URLs ❘ 289 public VirtualPathData GetVirtualPath(RequestContext requestContext, string name, RouteValueDictionary values) The fi rst method receives the current RequestContext and user-specifi ed route values (dictionary) used to select the desired route. 1. The route collection loops through each route and asks, “Can you generate read more..

  • Page - 326

    290 ❘ CHAPTER 9 ROUTING RouteCollection.GetVirtualPath(Supplied values) Does Route have required parameters? Required parameter is a URL parameter where there is no default supplied. Example: Route URL = {action}/{type} Defaults = type="list" {action} is required because it has no default, but {type} is not required because it has a default. Did the call to read more..

  • Page - 327

    Inside Routing: How Routes Generate URLs ❘ 291 Call match method, passing in supplied values For each constraint Does Route have constraints? Does constraint implement IRouteConstraint? If Route is a string, treat as regex. Does regex match? All constraints match. Yes Yes Yes Yes No No No No We are a match! Replace each URL parameter with the corresponding value (either supplied or read more..

  • Page - 328

    292 ❘ CHAPTER 9 ROUTING FIGURE 9-4 Table 9-6 shows the route data for this request. TABLE 9-6: Route Data KEY VALUE Controller Tasks Action List Page 2 To generate the URL for the next page, you only need to specify the route data that will change in the new request: @Html.ActionLink("Page 2", "List", new { page = 2 }) Even though read more..

  • Page - 329

    Inside Routing: How Routes Generate URLs ❘ 293 ambient values. To unset an ambient value when generating a URL, specify the key in the dictionary of parameters and have its value set to either null or an empty string. Overfl ow Parameters Overfl ow parameters are route values used in URL generation that are not specifi ed in read more..

  • Page - 330

    294 ❘ CHAPTER 9 ROUTING Table 9-7 shows parameters and the resulting URL. TABLE 9-7: Parameters and Resulting URL for GetVirtualPath PARAMETERS RESULTING URL REASON year=2007, month=1, day=12 /2007/1/12 Straightforward matching year=2007, month=1 /2007/1 Default for day = 1 Year=2007, month=1, day=12, category=123 /2007/1/12?category=123 “Overfl ow” parameters go into query string in read more..

  • Page - 331

    Custom Route Constraints ❘ 295 3. The Routing module calls the GetHttpHandler method of the IRouteHandler , which returns the IHttpHandler that will be used to process the request. 4. ProcessRequest is called on the HTTP handler, thus handing off the request to be handled. 5. In the case of ASP.NET MVC, the IRouteHandler is an instance of read more..

  • Page - 332

    296 ❘ CHAPTER 9 ROUTING When Routing evaluates route constraints, and a constraint value implements IRouteConstraint , it causes the route engine to call the IRouteConstraint.Match method on that route constraint to determine whether the constraint is satisfi ed for a given request. Route constraints are run for both incoming URLs and while generating read more..

  • Page - 333

    Summary ❘ 297 The only real difference from an MVC route is the last parameter, in which you direct the route to a Web Forms page. You can then use Page.RouteData to access the route parameter values, like this: protected void Page_Load(object sender, EventArgs e) { string term = RouteData.Values["term"] as string; Label1.Text = "Search read more..

  • Page - 334

    read more..

  • Page - 335

    NuGet —by Phil Haack and Jon Galloway WHAT’S IN THIS CHAPTER? ➤ NuGet Basics ➤ How to add a library as a package ➤ How to create packages ➤ How to publish packages WROX.COM CODE DOWNLOADS FOR THIS CHAPTER You can fi nd the code downloads for this chapter at proaspnetmvc5 on the Download Code tab. The code for read more..

  • Page - 336

    300 ❘ CHAPTER 10 NUGET The good news is that many developers don’t wait around to “scratch their own itch.” They solve their own problems (and those of their peers) with useful libraries that they write and then distribute on the Web. Three big challenges with all these libraries out there in the wild are discovery, read more..

  • Page - 337

    Adding a Library as a Package ❘ 301 ADDING A LIBRARY AS A PACKAGE NuGet is included with Visual Studio 2012 and 2013; it previously required a separate install with Visual Studio 2010. You install NuGet via a Visual Studio extension, and updates are available roughly every few months. You have two ways to interact with NuGet in read more..

  • Page - 338

    302 ❘ CHAPTER 10 NUGET When you fi nd a package, the pane on the right displays information about the package. Figure 10-3 shows the information pane for the SignalR package. FIGURE 10-2 FIGURE 10-3 read more..

  • Page - 339

    Adding a Library as a Package ❘ 303 This pane provides the following information: ➤ Created By: A list of authors of the original library. This listing does not show the owners of the package, just the authors. In some cases, the owners are different from the library authors. For example, the Bootstrap package is owned (maintained) by the Outercurve Foundation, read more..

  • Page - 340

    304 ❘ CHAPTER 10 NUGET NOTE In some cases, you’re prompted to accept the license terms for the pack- age, as well as any dependencies that also require license acceptance. Figure 10-4 shows what happens when you install the Microsoft.AspNet.SignalR pack- age. Requiring license acceptance is a setting in the package set by the package read more..

  • Page - 341

    Adding a Library as a Package ❘ 305 FIGURE 10-5 Also notice that you now have an assembly reference to the Elmah.dll assembly, as shown in Figure 10-6. FIGURE 10-6 Where is that assembly referenced from? To answer that, you need to look at what fi les are added to your solution when a package is installed. When the fi rst read more..

  • Page - 342

    306 ❘ CHAPTER 10 NUGET FIGURE 10-7 The packages folder contains a subfolder for each installed package. Figure 10-8 shows a packages folder with multiple installed packages. FIGURE 10-8 NOTE Note that the name of each package folder includes a version number because this folder stores all the packages installed for a given solution. The read more..

  • Page - 343

    Adding a Library as a Package ❘ 307 <configSections> <sectionGroup name="elmah"> <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" /> <section name="errorLog" requirePermission="false" read more..

  • Page - 344

    308 ❘ CHAPTER 10 NUGET Updating a Package NuGet doesn’t just help you install packages, it also helps you maintain them after installation. For example, let’s assume you’ve installed 10 or so packages in your project. At some point, you’re going to want to update some (or all) of your packages to the latest version of read more..

  • Page - 345

    Adding a Library as a Package ❘ 309 NuGet 2.7 simplifi ed things signifi cantly with the introduction of Automatic Package Restore. No manual steps are required either in your projects or in Visual Studio; MSBuild automatically per- forms a package restore step prior to building the application. NuGet looks at each package entry in every read more..

  • Page - 346

    310 ❘ CHAPTER 10 NUGET 2. Perform an action. This is done with commands such as Get-Package , which lists available packages online. This command supports search fi lters, as shown in Figure 10-11. FIGURE 10-11 3. Use tab expansions. Figure 10-12 shows an example of tab expansion at work with the Install-Package command. As you might guess, this command read more..

  • Page - 347

    Adding a Library as a Package ❘ 311 4. Compose commands. PowerShell also enables composing commands together by piping one command into another. For example, if you want to install a package into every project in your solution, you can run the following command: Get-Project -All | Install-Package log4net The fi rst command retrieves every project in your read more..

  • Page - 348

    312 ❘ CHAPTER 10 NUGET NOTE Generally the decision whether to use the Manage NuGet Packages dia- log versus the Package Manager Console comes down to a matter of preference: Do you like clicking or typing? However, the Package Manager Console sup- ports a few scenarios that are not available via the dialog: 1. Install a specifi c version read more..

  • Page - 349

    Creating Packages ❘ 313 After you have NuGet.exe installed, you have three main steps to follow to create a package: 1. Organize the package contents into a convention-based folder structure. 2. Specify the metadata for the package in a .nuspec fi le. 3. Run the NuGet.exe Pack command against the .nuspec fi le: Nuget Pack MyPackage.nuspec read more..

  • Page - 350

    314 ❘ CHAPTER 10 NUGET By default, the NuGet Pack command recursively includes all the fi les in the folder where the speci- fi ed .nuspec fi le is located. Overriding this default is possible by specifying the set of fi les to include within the .nuspec fi le. A package consists of three types of fi les, as outlined read more..

  • Page - 351

    Creating Packages ❘ 315 ➤ Source code transformations to insert Visual Studio project properties into the target source code. You do this with a .pp fi le extension (short for project properties). You most commonly use this to apply the project namespace to application code using the $rootnamespace$ property. All three transformation methods are described in detail read more..

  • Page - 352

    316 ❘ CHAPTER 10 NUGET Metadata Table 10-2 outlines the elements contained within the <metadata> sect ion of a NuSpec fi le. TABLE 10-2: Metadata Elements ELEMENT DESCRIPTION id Required. The unique identifi er for the package. version Required. The version of the package using the standard ver- sion format of up to four version segments (for example, 1.1 or read more..

  • Page - 353

    Creating Packages ❘ 317 ELEMENT DESCRIPTION references Names of assemblies within the lib folder that are added to the project as assembly references. Leave this blank if you want all assemblies in the lib folder to be added (the default behavior). If you specify any references, only those assemblies are added. dependencies The list of dependencies for the package specifi read more..

  • Page - 354

    318 ❘ CHAPTER 10 NUGET As mentioned in Table 10-3, the version attribute specifi es a range of versions. By default, just entering a version number, for example, <dependency id="MusicCategorizer" version="1.0" /> , indicates a minimum version for the dependency. This example shows a dependency that allows your package to take a read more..

  • Page - 355

    Creating Packages ❘ 319 include. For example, you might have a build process where you would rather choose the fi les to include rather than copy them into the convention-based structure fi rst. You can use the <files> element to choose which fi les to include. Note that if you specify any fi les, the conventions are ignored and only the read more..

  • Page - 356

    320 ❘ CHAPTER 10 NUGET billiards). First, you ask the 8-ball any yes or no question that pops in your head. You then shake it and peer into a small clear window that allows you to see one face of an icosahedral (20-sided) die with the answer to the question. You’ll build your own version of the Magic 8-Ball read more..

  • Page - 357

    Creating Packages ❘ 321 Your init.ps1 script is very simple. It imports a PowerShell module that contains your real logic: param($installPath, $toolsPath, $package, $project) Import-Module (Join-Path $toolsPath MagicEightBall.psm1) The fi rst line declares the parameters to the script that NuGet will pass into the script when NuGet calls the script. The second read more..

  • Page - 358

    322 ❘ CHAPTER 10 NUGET values for each parameter to the function. Each entry in the dictionary has a key correspond- ing to the parameter name. In this example, you only have one parameter, question . The value of each entry is an array of possible values. This code sample provides three possible questions you can ask the 8-ball, but of course, the user of read more..

  • Page - 359

    Creating Packages ❘ 323 When NuGet installs an assembly from a package, it checks the target .NET Framework version of the project you are adding the package to. NuGet then selects the correct version of the assembly in the package by selecting the correct subfolder within the lib folder. Figure 10-15 shows an example of the layout read more..

  • Page - 360

    324 ❘ CHAPTER 10 NUGET Profi les supported by NuGet include: ➤ CF: Compact Framework ➤ Client: Client Profi le ➤ Full: Full Profi le ➤ WP: Windows Phone Figure 10-16 shows a relatively complex example used by the Portable.MvvmLightLibs package to support a variety of platforms. FIGURE 10-16 Prerelease Packages By default, NuGet displays read more..

  • Page - 361

    Publishing Packages ❘ 325 PUBLISHING PACKAGES The previous section looked at how to create packages. Creating packages is useful, but at some point, you might to want to share them with the world. This section explains how to publish your packages to the NuGet Gallery. USING PRIVATE NUGET FEEDS If you don’t want to—or can’t—share read more..

  • Page - 362

    326 ❘ CHAPTER 10 NUGET FIGURE 10-17 FIGURE 10-18 read more..

  • Page - 363

    Publishing Packages ❘ 327 FIGURE 10-19 Uploading a package takes you to a screen that enables you to verify the metadata for the package, as shown in Figure 10-20. If you want to upload the package but keep it hidden from search results, change the Listed in Search Results option. NOTE The package can still be installed if you know read more..

  • Page - 364

    328 ❘ CHAPTER 10 NUGET FIGURE 10-20 Conveniently, there’s also a Reset button in case you accidentally leak your key, much like I just did by posting this screenshot. When you use the NuGet push command, it requires that you specify your API key. However, you can use the setApiKey command to have NuGet remember your API read more..

  • Page - 365

    Publishing Packages ❘ 329 FIGURE 10-21 FIGURE 10-22 This makes the package immediately available in the feed and thus available for installation via the dialog or console. Note that it might take a few minutes before this change is refl ected in the nuget .org website. read more..

  • Page - 366

    330 ❘ CHAPTER 10 NUGET FIGURE 10-23 Using the Package Explorer After building your package, you might want to examine the package to ensure that it has been packaged up properly. All NuGet packages are, at their core, simply zip fi les. You can rename the fi le to have a .zip fi le extension and then unzip the contents to read more..

  • Page - 367

    Publishing Packages ❘ 331 After installing the Package Explorer, you can double-click any .nupkg fi le to view its contents or even open directly from the NuGet feed. Figure 10-24 shows the MVC 5 NuGet package open in NuGet Package Explorer. You can also use the Package Explorer to make quick edits to a package fi le or even to create read more..

  • Page - 368

    332 ❘ CHAPTER 10 NUGET FIGURE 10-26 SUMMARY Although NuGet ships with ASP.NET MVC 5 and complements it nicely, NuGet is not restricted to ASP.NET MVC by any means. NuGet can install packages for nearly any type of project within Visual Studio. Are you building a Windows Phone application? There’s a set of NuGet packages for it. read more..

  • Page - 369

    ASP.NET Web API —by Brad Wilson WHAT’S IN THIS CHAPTER? ➤ How to defi ne ASP.NET Web API ➤ Using the new ASP.NET Project wizard ➤ The basics of writing an API controller ➤ Confi guring web-hosted and self-hosted Web API ➤ How to add Web API and MVC routing ➤ How to bind parameters ➤ How to fi lter requests ➤ How to enable read more..

  • Page - 370

    334 ❘ CHAPTER 11 ASP.NET WEB API IT applications in businesses—from the desktop and into the browser. A major accelerator of that shift was XMLHTTP, originally shipped with Internet Explorer 5, which when combined with JavaScript, allowed web developers to communicate back from their browser applications to the server. Google showed the world what read more..

  • Page - 371

    Writing an API Controller ❘ 335 GETTING STARTED WITH WEB API ASP.NET MVC 5 ships as part of Visual Studio 2013 and as an add-on for Visual Studio 2012. The installer includes all the components of ASP.NET Web API 2. The New ASP.NET Project wizard, shown in Figure 11-1, allows the user to add Web API features to any project type, including read more..

  • Page - 372

    336 ❘ CHAPTER 11 ASP.NET WEB API public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 public string Get(int id) { read more..

  • Page - 373

    Writing an API Controller ❘ 337 (most notably Response and anything related to MVC views). It’s also worth noting that the pub- lic interface of this class has grown by a substantial margin compared to v1 due to the new action result methods. LISTING 11-2: ApiController public interface namespace System.Web.Http { public abstract class read more..

  • Page - 374

    338 ❘ CHAPTER 11 ASP.NET WEB API HttpStatusCode statusCode, T value, MediaTypeFormatter formatter, string mediaType); protected virtual FormattedContentResult<T> Content<T>( read more..

  • Page - 375

    Writing an API Controller ❘ 339 protected virtual OkResult Ok(); protected virtual OkNegotiatedContentResult<T> Ok<T>( T content); protected virtual RedirectResult Redirect( read more..

  • Page - 376

    340 ❘ CHAPTER 11 ASP.NET WEB API Incoming Action Parameters To accept incoming values from the request, you can put parameters on your action, and just like MVC, the Web API framework will automatically provide values for those action parameters. Unlike MVC, there is a strong line drawn between values from the HTTP body and values taken read more..

  • Page - 377

    Writing an API Controller ❘ 341 you would with MVC controllers and ActionResult . The ApiController class includes many sets of methods that directly return action results; their resulting behavior is described in the following list: ➤ BadRequest : Returns an HTTP 400 (“Bad Request”). Optionally includes either a message or an automatically formatted read more..

  • Page - 378

    342 ❘ CHAPTER 11 ASP.NET WEB API A fi nal note about action return values: If your action is asynchronous in nature (that is, it con- sumes other asynchronous APIs), you can modify the signature of your action return value to be Task<T> and use the async and await features in .NET 4.5 to seamlessly convert your sequen- read more..

  • Page - 379

    Confi guring Web API ❘ 343 Confi guration in Web-Hosted Web API The default MVC project templates are all web-hosted projects because MVC only supports web- hosting. Inside the App_Startup folder are the startup confi guration fi les for your MVC application. The Web API confi guration code is in WebApiConfig.cs (or .vb ), and looks read more..

  • Page - 380

    344 ❘ CHAPTER 11 ASP.NET WEB API When self-hosting, you are responsible for creating the confi guration and starting and stopping the Web API server as appropriate. Each self-host system uses a slightly different confi guration system, as described in the following sections. Confi gurating WCF Self-Host The confi guration class you need to read more..

  • Page - 381

    Confi guring Web API ❘ 345 Because OWIN is about abstracting the web server from the web application, you also need to choose a way to connect your app to your web server of choice. The NuGet package Microsoft .AspNet.WebApi.OwinSelfHost brings in parts of the Katana project to make it easy to self-host your Web APIs using read more..

  • Page - 382

    346 ❘ CHAPTER 11 ASP.NET WEB API For these reasons, I recommend that if you have new projects with self-hosted Web API, you should choose OWIN. Although nothing is wrong with the WCF self-host, it is clearly going to be a “legacy” solution, whereas most of ASP.NET moves forward on the OWIN platform. ADDING ROUTES TO YOUR WEB read more..

  • Page - 383

    Binding Parameters ❘ 347 by using the {action} matching token in the route (or by adding an action value to the default values for the route). When the route contains an action value, Web API uses that action name to fi nd the appropriate action method. Even when using action name -based routing, the default verb mappings read more..

  • Page - 384

    348 ❘ CHAPTER 11 ASP.NET WEB API The parameter binding system is quite different from the way MVC works. In MVC, all parameters are created through model binding. Model binding in Web API works mostly the same way as MVC (model binders and providers, and value providers and factories), although it’s been re-factored quite a bit, based read more..

  • Page - 385

    Filtering Requests ❘ 349 FILTERING REQUESTS The ability to fi lter requests with attributes has been in ASP.NET MVC since version 1.0, and the ability to add global fi lters was added in MVC 3. ASP.NET Web API includes both features, although as discussed previously, the fi lter is global at the confi guration level, not at the read more..

  • Page - 386

    350 ❘ CHAPTER 11 ASP.NET WEB API You have no equivalent to the MVC HandleError attribute in Web API. When an MVC applica- tion encounters an error, its default behavior is to return the ASP.NET “yellow screen of death.” This is appropriate (if not entirely user friendly) when your application is generating HTML. The HandleError read more..

  • Page - 387

    Exploring APIs Programmatically ❘ 351 FIGURE 11-2 @model System.Web.Http.Description.IApiExplorer @foreach (var api in Model.ApiDescriptions) { <h1>@api.HttpMethod @api.RelativePath</h1> if (api.ParameterDescriptions.Any()) { <h2>Parameters</h2> <ul> @foreach (var param in api.ParameterDescriptions) { read more..

  • Page - 388

    352 ❘ CHAPTER 11 ASP.NET WEB API TRACING THE APPLICATION One of the most challenging things with remotely deployed code is debugging when something has gone wrong. Web API enables a very rich automatic tracing ecosystem that is turned off by default but can be enabled by the developer as needed. The built-in tracing functionality wraps many read more..

  • Page - 389

    Web API Example: ProductsController ❘ 353 LISTING 11-5: ProductsController.cs public class ProductsController : ApiController { private DataContext db = new DataContext(); // GET api/Products public IEnumerable<Product> GetProducts() { return db.Products; } // GET api/Products/5 public IHttpActionResult GetProduct(int read more..

  • Page - 390

    354 ❘ CHAPTER 11 ASP.NET WEB API Url.Link( "DefaultApi", new { id = product.ID })); return Created(uri, product); } else { Return read more..

  • Page - 391

    Single Page Applications with AngularJS —by K. Scott Allen WHAT’S IN THIS CHAPTER? ➤ Understanding and installing AngularJS ➤ How to build the Web API ➤ How to build applications and models WROX.COM CODE DOWNLOADS FOR THIS CHAPTER You can fi nd the code downloads for this chapter at proaspnetmvc5 on the Download read more..

  • Page - 392

    356 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS controls on a page and push the input data into JavaScript objects. The typical browser application also manages multiple views by loading pieces of HTML into the DOM, which also requires the application to manage browser history for the back and forward buttons to work. With all this read more..

  • Page - 393

    Understanding and Setting Up AngularJS ❘ 357 update, list, and show the details for movies, but instead of using ASP.NET MVC views to create HTML you’ll use Angular to manage the different views. Instead of navigating to different URLs, you’ll keep the browser on the same original page. Instead of sending HTML from the server you’ll read more..

  • Page - 394

    358 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS FIGURE 12-2 After you create the project, you can run the application and see the home page working, as shown in Figure 12-3. FIGURE 12-3 read more..

  • Page - 395

    Understanding and Setting Up AngularJS ❘ 359 Now, you can confi gure the home page to use Angular. Adding AngularJS to the Site You have different approaches for installing Angular. If you are particular about the Angular ver- sion and features you need, you might go to the Angular website ( and download the script fi les directly. read more..

  • Page - 396

    360 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS Adding Angular to the home page is easy because the default layout view includes a section named “scripts” th at allows you to place script tags at the bottom of a page. You can also use the bundling and minifi cation features of ASP.NET to minify the Angular script, but read more..

  • Page - 397

    Understanding and Setting Up AngularJS ❘ 361 The examples you’ve seen so far might make templates that look too simple to be useful, but later you’ll see how templates provide powerful two-way data binding between a view (the HTML) and a model (a JavaScript object). If the user modifi es a value in a view (by typing into an input, read more..

  • Page - 398

    362 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS Migrations create a Migrations folder in the project with a Configuration.cs fi le. Inside Configuration.cs you’ll fi nd a class with a Seed method. You can add the following code to the Seed method to populate the database with three movie objects. protected override void read more..

  • Page - 399

    Building the Web API ❘ 363 BUILDING THE WEB API The Web API is simple to build because you only need basic create, read, update, and delete func- tionality, and the scaffolding provided by Visual Studio 2013 can generate the code you need. Just follow these steps: 1. Right-click the Controllers folder and select Add ➪ Controller, which opens the read more..

  • Page - 400

    364 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS FIGURE 12-8 FIGURE 12-9 You now have all the code you need on the server. The rest of the chapter focuses on client code and AngularJS. BUILDING APPLICATIONS AND MODULES So far you’ve bootstrapped an Angular application in the home page of the website, but you’ve only used read more..

  • Page - 401

    Building Applications and Modules ❘ 365 Various features of the Angular framework are organized into different modules that you’ll need for the application. But, before you use these modules you need a custom module for your application itself. To start, follow these steps: 1. Create a new folder in the project named Client. Some people might read more..

  • Page - 402

    366 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS To create a controller to show a list of movies, fi rst create a new script in the Client/Scripts folder named ListController.js with the following contents: (function(app) { }(angular.module("atTheMovies"))); The code uses an immediately invoked function expression to avoid creating read more..

  • Page - 403

    Building Applications and Modules ❘ 367 </div> </div> The ng-controller directive attaches the ListController to a div inside the application. Angular fi nds the controller by name and creates the controller. By adding an Angular template to the markup, you’ll see a controller, view, and model: <div data-ng-app="atTheMovies"> read more..

  • Page - 404

    368 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS Although you barely have any functionality in the application, the code so far demonstrates three key abstractions: ➤ Controllers are responsible for putting together a model by augmenting the $scope variable. Controllers avoid manipulating the DOM directly. Instead, changes in the UI are propagated read more..

  • Page - 405

    Building Applications and Modules ❘ 369 Because Angular relies on the names of the parameters, you must be careful if you minify your scripts because most JavaScript minifi ers change local variables and function parameter names to make the names as short as possible (thereby making the overall script smaller for download). Angular offers a read more..

  • Page - 406

    370 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS The previous code uses the promise object to register a success handler that sets the data returned from the server (a collection of movies) to a movies member of the $scope object. Now movies become available as part of the model for the view. Over in the Index.cshtml read more..

  • Page - 407

    Building Applications and Modules ❘ 371 inside of a view before the chapter is complete. But, I also want to show a different approach to implementing the additional functionality using separate views and the routing features of Angular. Routing Routing in Angular is conceptually similar to routing in ASP.NET. Given some URL, such as / read more..

  • Page - 408

    372 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS }; app.config(config); }()); The $routeProvider offers methods, such as when and otherwise to describe the URL scheme for a single page. In the other words, “/list” is saying if the URL is /home/index#/list , then load the list.html view from the Client/Views read more..

  • Page - 409

    Building Applications and Modules ❘ 373 The contents of list.html is the markup that used to be inside the ng-app div . <div ng-controller="ListController"> <table> <tr ng-repeat="movie in movies"> <td>{{movie.Title}}</td> </tr> </table> </div> read more..

  • Page - 410

    374 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS var id = $; $http.get("/api/movie/" + id) .success(function(data) { $ = data; }); }; app.controller("DetailsController", read more..

  • Page - 411

    Building Applications and Modules ❘ 375 A Custom MovieService With Angular you can defi ne custom controllers and models, but you can also create custom direc- tives, services, modules, and more. For this application, you might make use of a custom service that wraps the capabilities of the MoviesController Web API so your controllers don’t read more..

  • Page - 412

    376 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS the constant method. These values take a key as the fi rst parameter and the value to associate with the key as the second parameter. (function () { var app = angular.module("atTheMovies", ["ngRoute"]); var config = function($routeProvider) { read more..

  • Page - 413

    Building Applications and Modules ❘ 377 The DetailsController can also use the service: (function(app) { var DetailsController = function($scope, $routeParams, movieService) { var id = $; movieService .getById(id) .success(function(data) { read more..

  • Page - 414

    378 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS FIGURE 12-14 The model inside of ListController is now responsible for providing an implementation for delete: (function(app) { var ListController = function ($scope, movieService) { movieService .getAll() read more..

  • Page - 415

    Building Applications and Modules ❘ 379 app.controller("ListController", ListController); }(angular.module("atTheMovies"))); You have two new functions in the latest version of the ListController . The fi rst function is the delete method attached to $scope . As a method on the $scope object, delete is reachable by the ng-click read more..

  • Page - 416

    380 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS class="form-control" /> </div> <button class="btn btn-default" ng-click="save()">Save </button> read more..

  • Page - 417

    Building Applications and Modules ❘ 381 The view now includes a button to invoke a create method on the model, and uses the ng-include directive to compose the edit view into itself. Pay special attention to the single quotes in the value of the ng-include directive. The quotes ensure the path to the view is recognized as a string read more..

  • Page - 418

    382 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS Released in {{movie.ReleaseYear}}. </div> <div> {{movie.Runtime}} minutes long. </div> <button ng-click="edit()">Edit</button> <div ng-include="'/Client/views/edit.html'"></div> </div> The read more..

  • Page - 419

    Building Applications and Modules ❘ 383 }; var updateMovie = function () { movieService.update($ .success(function () { angular.extend($, $; read more..

  • Page - 420

    384 ❘ CHAPTER 12 SINGLE PAGE APPLICATIONS WITH ANGULARJS feel like the edit code is tightly coupled to the parent controller, an alternative is to use $scope.emit to raise an event so the other controllers can handle the update and save functionality on their own. SUMMARY This chapter was a fast tour of some basic AngularJS read more..

  • Page - 421

    Dependency Injection —by Brad Wilson WHAT’S IN THIS CHAPTER? ➤ Understanding software design patterns ➤ Using the dependency resolver in MVC ➤ Using the dependency resolver in Web API As of version 3, ASP.NET MVC has included a dependency resolver that dramatically improves the ability of an application to participate in dependency injection for read more..

  • Page - 422

    386 ❘ CHAPTER 13 DEPENDENCY INJECTION DESIGN PATTERNS The concept of patterns and a pattern language is generally credited to Christopher Alexander, Sara Ishikawa, and Murray Silverstein in their book A Pattern Language: Towns, Buildings, and Construction (1977, Oxford University Press). The book presents a view of architecture and urban planning in read more..

  • Page - 423

    Software Design Patterns ❘ 387 the notifi cation system knows exactly what kind of service class it’s creating and consuming. This coupling is an indication of how interconnected your code is. A class that knows a lot about the other classes it interacts with (as in the preceding example) is said to be tightly coupled. In software read more..

  • Page - 424

    388 ❘ CHAPTER 13 DEPENDENCY INJECTION NOTE Moving the creation of dependencies outside of the class that consumes those dependencies is called the inversion of control pattern, so named because what you’re inverting here is the creation of dependencies (and in so doing, you are removing the control of dependency creation from the read more..

  • Page - 425

    Software Design Patterns ❘ 389 public void InterestingEventHappened() { svc.SendMessage(); } } This assumes that anybody who creates an instance of NotificationSystem will have access to a service locator. What’s convenient is that if your application creates instances of read more..

  • Page - 426

    390 ❘ CHAPTER 13 DEPENDENCY INJECTION public void InterestingEventHappened() { svc.SendMessage(); } } This code is a little less pretty than the previous version, owing primarily to the required casting to IMessagingService . With the introduction of generics in .NET 2.0, you could have read more..

  • Page - 427

    Software Design Patterns ❘ 391 The downside to this weakly typed service locator approach is that it forces implementers of IServiceLocator to create two nearly identical methods instead of one. This unfortunate duplica- tion of effort can be eliminated with a feature introduced into .NET 3.5: extension methods. Extension methods are written read more..

  • Page - 428

    392 ❘ CHAPTER 13 DEPENDENCY INJECTION On the other hand, a weakly typed locator interface doesn’t communicate anything about the kinds of services that might be requested, and it doesn’t offer a simple way to customize the creation of the service. You could add an arbitrary optional array of objects as “creation parameters” for the read more..

  • Page - 429

    Software Design Patterns ❘ 393 public NotificationSystem(IMessagingService service) { this.svc = service; } public void InterestingEventHappened() { svc.SendMessage(); } } In this code, the fi rst benefi t is that the implementation of read more..

  • Page - 430

    394 ❘ CHAPTER 13 DEPENDENCY INJECTION You should update the InterestingEventHappened method to ensure that it has been provided with its dependency before using the service: public void InterestingEventHappened() { if (MessagingService == null) { throw new InvalidOperationException( read more..

  • Page - 431

    Dependency Resolution in MVC ❘ 395 The difference is in the details, of course. The implementation of a service locator is typically very simple: You tell the service locator, “If anybody asks for this type, you give them this object.” Service locators are rarely involved in the process of actually creating the object in question. read more..

  • Page - 432

    396 ❘ CHAPTER 13 DEPENDENCY INJECTION USING NUGET TO GET YOUR CONTAINER Not having to implement the IDependencyResolver interface on your own, just because you want to use dependency injection, certainly would be ideal. Thankfully, NuGet can come to the rescue here. NuGet is the package manager included with ASP.NET MVC. It enables you to read more..

  • Page - 433

    Dependency Resolution in MVC ❘ 397 Singly Registered Services in MVC MVC has services that it consumes for which the user can register one (and exactly one) instance of that service. It calls these services singly registered services, and the method used to retrieve singly registered services from the resolver is GetService . For all the singly read more..

  • Page - 434

    398 ❘ CHAPTER 13 DEPENDENCY INJECTION the dependency resolver API and the traditional registration API, and MVC combines the results in a single merged services list. Services registered in the dependency resolver come before services reg- istered with the traditional registration APIs. This is important for those multiply registered services that read more..

  • Page - 435

    Dependency Resolution in MVC ❘ 399 Service: View Engine Interface: IViewEngine Traditional Registration API: ViewEngines.Engines Multi-service model: competitive Default Service Implementations: ➤ WebFormViewEngine ➤ RazorViewEngine Service: Model Validator Provider Type: ModelValidatorProvider Traditional Registration API: ModelValidatorProviders.Providers Multi-service model: cooperative read more..

  • Page - 436

    400 ❘ CHAPTER 13 DEPENDENCY INJECTION As you saw in the previous two sections, two services called activators control the instantiation of controllers and view pages. The default implementations of these activators ask the dependency resolver to create the controllers and view pages, and failing that, they will fall back to calling read more..

  • Page - 437

    Dependency Resolution in MVC ❘ 401 as the route data from the route that mapped to the request. You may also choose to implement a controller activator to help make contextual decisions about how to create your controller objects, because it has access to the context information. One example of this might be an activator that chooses read more..

  • Page - 438

    402 ❘ CHAPTER 13 DEPENDENCY INJECTION Examples of third-party libraries that did this were the earlier releases of the SubSonic project, an object-relational mapper (ORM) written by Rob Conery. In this case, SubSonic would consume a fi le that described a database to be mapped, and at run time it would generate the ORM classes read more..

  • Page - 439

    Dependency Resolution in Web API ❘ 403 For all the singly registered services, Web API consults the dependency resolver for the service the fi rst time it is needed, and caches the result for the lifetime of the application. When Web API cannot fi nd the service in the resolver, it uses the service found in the default services read more..

  • Page - 440

    404 ❘ CHAPTER 13 DEPENDENCY INJECTION Service: Filter Provider Interface: IFilterProvider Multi-service model: cooperative Default Service Implementations: ➤ ConfigurationFilterProvider ➤ ActionDescriptorFilterProvider Service: Model Binder Provider Type: ModelBinderProvider Multi-service model: competitive Default Service Implementations: ➤ TypeConverterModelBinderProvider ➤ read more..

  • Page - 441

    Summary ❘ 405 Arbitrary Objects in Web API Three special cases exist where the Web API framework will request a dependency resolver to manufacture arbitrary objects—that is, objects that are not (strictly speaking) services. Like MVC, controllers are one class of these objects. The other two are model binders attached with the [ModelBinder] attribute and read more..

  • Page - 442

    read more..

  • Page - 443

    Unit Testing —by Brad Wilson WHAT’S IN THIS CHAPTER? ➤ Understanding unit testing and test-driven development ➤ Building a unit test project ➤ Advice for unit testing your ASP.NET MVC and ASP.NET Web API applications Unit testing and developing testable software have become recognized as essential elements in the software quality process. Most professional read more..

  • Page - 444

    408 ❘ CHAPTER 14 UNIT TESTING The second half of this chapter includes real-world advice for unit testing your ASP.NET MVC and Web API applications. Those who are already practicing unit testing and want to get the most out of their craft might want to skip directly to the second half of the chapter. UNDERSTANDING UNIT TESTING AND read more..

  • Page - 445

    Understanding Unit Testing and Test-Driven Development ❘ 409 Testing in isolation has an additional benefi t because the code with which you will eventually inter- act might not yet exist. This is particularly true when you’re working on larger teams with several active developers; several teams might handle interacting pieces of functionality and read more..

  • Page - 446

    410 ❘ CHAPTER 14 UNIT TESTING their knowledge of the production code and the desired end-user behavior to create the list of tests that help assure them that the code behaves as intended. Unfortunately, weaknesses exist with this ordering of tests after production code. Developers can easily overlook some piece of the production code that read more..

  • Page - 447

    Understanding Unit Testing and Test-Driven Development ❘ 411 practiced regularly, this process teaches you when to stop writing new code. Just do enough to make a test pass, and then stop; if you’re tempted to keep going, describe the new behavior you want to implement in another test. This not only gives you the bug quality benefi ts read more..

  • Page - 448

    412 ❘ CHAPTER 14 UNIT TESTING stack.Push(value); // Act string result = stack.Pop(); // Assert Assert.AreEqual(value, result); } I’ve added the Arrange , Act , and Assert comments here to illustrate the structure of the test. The arrange in this case creates an empty stack and pushes a value onto it. These are the read more..

  • Page - 449

    Building a Unit Test Project ❘ 413 FIGURE 14-1 By selecting the Add Unit Tests checkbox, you’re telling the ASP.NET New Project Wizard not only to create an associated unit test project, but also to populate it with a set of default unit tests. These default unit tests can help new users understand how to write tests against an read more..

  • Page - 450

    414 ❘ CHAPTER 14 UNIT TESTING This is a pretty good unit test: It’s written in 3A form, and at three lines of code, it’s quite simple to understand. However, even this unit test has room for improvement. Our action method is only one line of code, but it’s actually doing two things: ➤ It returns a view result. read more..

  • Page - 451

    Advice for Unit Testing Your ASP.NET MVC and ASP.NET Web API Applications ❘ 415 Test Only the Code You Write One of the more common mistakes that people new to unit testing and TDD make is to test code they didn’t write, even if inadvertently. Your tests should be focused on the code that you wrote, and not the code or logic read more..

  • Page - 452

    416 ❘ CHAPTER 14 UNIT TESTING Testing Controllers The default unit test project already includes some controller tests (which you modifi ed earlier in this chapter). A surprising number of subtleties are involved with testing controllers, and as with all things, the subtleties between decent and great code can often be found in small read more..

  • Page - 453

    Advice for Unit Testing Your ASP.NET MVC and ASP.NET Web API Applications ❘ 417 but also trivial to support the idea of getting services via constructor parameters. Both frameworks can support most any dependency injection framework through third-party libraries available on NuGet. You can now leverage that work very easily in your unit tests to read more..

  • Page - 454

    418 ❘ CHAPTER 14 UNIT TESTING Favoring Action Results over HttpContext Manipulation You can think of the ASP.NET core infrastructure as the IHttpModule and IHttpHandler inter- faces, plus the HttpContext hierarchy of classes (HttpRequest, HttpResponse , and so on). These are the fundamental underlying classes that all ASP.NET is built upon, whether read more..

  • Page - 455

    Advice for Unit Testing Your ASP.NET MVC and ASP.NET Web API Applications ❘ 419 That’s a couple of extra ugly lines of code, even after you fi gure out how to write them! Redirect is probably one of the simplest things you can do, too. Imagine that you had to write code like this every time you wanted to write a test for read more..

  • Page - 456

    420 ❘ CHAPTER 14 UNIT TESTING The id parameter and the person variable are using the two aforementioned techniques. The unit testing benefi t to using the action parameter should be obvious: It’s trivial for the unit test to provide an instance of whatever type your action method needs, and no need exists to change any of the read more..

  • Page - 457

    Advice for Unit Testing Your ASP.NET MVC and ASP.NET Web API Applications ❘ 421 The default MVC project template registers two routes inside of your global.asax fi le: public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", read more..

  • Page - 458

    422 ❘ CHAPTER 14 UNIT TESTING .Returns("~/handler.axd"); var routes = new RouteCollection(); MvcApplication.RegisterRoutes(routes); // Act RouteData routeData = routes.GetRouteData(mockContext.Object); // Assert Assert.IsNotNull(routeData); Assert.IsInstanceOfType(routeData.RouteHandler, read more..

  • Page - 459

    Advice for Unit Testing Your ASP.NET MVC and ASP.NET Web API Applications ❘ 423 you have three replaceable parts to this route, you’ll end up with four tests that probably have data and results like those shown in Table 14-1. If your unit-testing framework supports data-driven tests, routes are an excellent place to take advantage of read more..

  • Page - 460

    424 ❘ CHAPTER 14 UNIT TESTING A validation attribute derives from the ValidationAttribute base class, from System .ComponentModel.DataAnnotations . Implementing validation logic means overriding one of the two IsValid methods. You might recall the maximum words validator from Chapter 6, which started out like this: public class MaxWordsAttribute : ValidationAttribute read more..

  • Page - 461

    Advice for Unit Testing Your ASP.NET MVC and ASP.NET Web API Applications ❘ 425 IsValid . Theoretically, any implementation of IsValid must be resilient when being called without a validation context because it might be called by code that was written against the .NET 3.5 data annotations API; in practice, though, any validator that is used read more..

  • Page - 462

    426 ❘ CHAPTER 14 UNIT TESTING TABLE 14-3: Validation Context for Property Validation PROPERT Y WHAT IT SHOULD CONTAIN DisplayName This property is used in error messages, replacing the {0} replacement token. For property validation, it is usually the name of the property, although that name might be infl uenced by attributes such as [Display] or [DisplayName] . read more..

  • Page - 463

    Summary ❘ 427 MemberName = "FirstName" }; var validator = new ValidationAttributeUnderTest(); validator.Validate(model.FirstName, context); Comparing this code to the previous example, you can see two key differences: ➤ The code sets the value of MemberName to match the property name, whereas the model-level validation sample didn’t set any value for MemberName . read more..

  • Page - 464

    read more..

  • Page - 465

    Extending MVC —by Brad Wilson and David Matson WHAT’S IN THIS CHAPTER? ➤ Extending models ➤ Extending views ➤ Extending controllers WROX.COM CODE DOWNLOADS FOR THIS CHAPTER All code for this chapter is provided via NuGet, as described in the introduction at the front of this book. Throughout the chapter, NuGet code samples are clearly read more..

  • Page - 466

    430 ❘ CHAPTER 15 EXTENDING MVC Some developers won’t ever need to know about the underlying extensibility of the platform; at best, they will use it indirectly by consuming a third-party extension to MVC. For the rest, the avail- ability of these customization points is a critical factor in deciding how best to use MVC in their read more..

  • Page - 467

    Extending Models ❘ 431 Value providers come from value provider factories, and the system searches for data from those value providers in their registered order (the preceding list is the order that is used by default, top fi rst to bottom last). Developers can write their own value provider factories and value provid- ers, and insert them read more..

  • Page - 468

    432 ❘ CHAPTER 15 EXTENDING MVC The full sample does include support for validation, but it makes the example a bit more detailed. In some instances, you know the types you’re model binding against, so supporting generic validation might not be necessary (because you could hard-code the validation logic directly into the model binder); for read more..

  • Page - 469

    Extending Models ❘ 433 Our call to the Get method invokes validation, so we need to give the validation system a container object of some sort, even though we know it’s not the fi nal container. The Get method has several pieces to it. Here’s the whole function, and then you’ll examine the code a few lines at a time: private TModel read more..

  • Page - 470

    434 ❘ CHAPTER 15 EXTENDING MVC if (invalidValue && modelState.Errors.Count == 0) modelState.Errors.Add( String.Format( "The value '{0}' is not a valid value for {1}.", attemptedValue, metadata.GetDisplayName() read more..

  • Page - 471

    Extending Models ❘ 435 the metadata so that validation has a value to run against. If you can successfully convert the value, then you can use that; otherwise, you use the attempted value, even though you know it’s not the right type. TModel model; bool invalidValue = false; try { model = (TModel)valueProviderResult.ConvertTo(typeof(TModel)); metadata.Model = model; read more..

  • Page - 472

    436 ❘ CHAPTER 15 EXTENDING MVC so that you can easily see the server-side logic being run and debug into it. You should turn on cli- ent-side validation inside the view so that you can verify that the client-side validation rules remain in place and functional. Describing Models with Metadata The model metadata system was introduced in read more..

  • Page - 473

    Extending Models ❘ 437 A derived type, AssociatedMetadataProvider , can be used by metadata providers that intend to provide metadata via attributes. It consolidates the three method calls into a single one named CreateMetadata , and passes along the list of attributes that were attached to the model and/or model properties. If you’re writing a read more..

  • Page - 474

    438 ❘ CHAPTER 15 EXTENDING MVC ModelMetadata metadata = base.CreateMetadata( attributes, containerType, modelAccessor, modelType, propertyName ); // Look inside our modifier dictionary for read more..

  • Page - 475

    Extending Models ❘ 439 on their model properties. In the box in .NET 3.5 SP1 are four validation attributes: [Required] , [Range] , [StringLength] , and [RegularExpression] . A base class, ValidationAttribute , is provided for developers to write their own custom validation logic. The CLR team added a few enhancements to the validation system in .NET 4, read more..

  • Page - 476

    440 ❘ CHAPTER 15 EXTENDING MVC We have implemented three different validators for this example, including both server-side and client-side validation support. The registration API looks nearly identical to the model metadata-fl uent API example examined previously. Our implementation of GetValidators is based on a dictionary that maps requested read more..

  • Page - 477

    Extending Models ❘ 441 This code looks up all the validator factories that have been registered with the provider. The func- tions you saw in registration, like Required and StringLength , are how those validator factories get registered. All those functions tend to follow the same pattern: public ValidatorRegistrar<TModel> Required( read more..

  • Page - 478

    442 ❘ CHAPTER 15 EXTENDING MVC The full example includes implementation of three validation rules (Required, StringLength , and EmailAddress ), including a model, controller, and view, which shows it all working together. Client-side validation has been turned off by default so that you can verify and debug into the server-side validation. You can read more..

  • Page - 479

    Extending Views ❘ 443 "~/Areas/{2}/Views/Shared/{0}.master" }; AreaViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.aspx", "~/Areas/{2}/Views/{1}/{0}.ascx", "~/Areas/{2}/Views/Shared/{0}.aspx", "~/Areas/{2}/Views/Shared/{0}.ascx" }; AreaPartialViewLocationFormats = AreaViewLocationFormats; MasterLocationFormats = new string[] { read more..

  • Page - 480

    444 ❘ CHAPTER 15 EXTENDING MVC views, views, and partial views; it also does not have separate fi le types for pages versus controls because those constructs don’t exist in Razor. After you have the customized view engine, you’ll need to let MVC know to use it. In addition, you’ll need to remove the existing view engine read more..

  • Page - 481

    Extending Views ❘ 445 Extension methods in MVC 1.0 all tended to return values of the String type, and that value would be directly placed into the output stream with a call much like this one (Web Forms view syntax): <%= Html.MyExtensionMethod() %> Unfortunately, a problem existed with the old Web Forms syntax: letting unintended HTML read more..

  • Page - 482

    446 ❘ CHAPTER 15 EXTENDING MVC EXTENDING CONTROLLERS Controller actions are the glue that pulls together your application; they talk to models via data access layers, make rudimentary decisions about how to achieve activities on behalf of the user, and decide how to respond (with views, JSON, XML, and so on). Customizing how actions are read more..

  • Page - 483

    Extending Controllers ❘ 447 If a method selector returns false when MVC calls its IsValidForRequest method, the method is not considered valid for the given request and the system keeps looking for a match. If the method has no selectors, it’s considered a potentially valid target for dispatching; if the method has one or more selectors, they read more..

  • Page - 484

    448 ❘ CHAPTER 15 EXTENDING MVC ➤ Pre- and post-processing of results ➤ Error handling A sixth kind of fi lter, an override fi lter, allows specifying exceptions to the default set of global or controller fi lters. Filters can be written as attributes that are applied directly to the action methods (or controller classes), or as read more..

  • Page - 485

    Extending Controllers ❘ 449 So if your action uses bearer token authentication, and you want to avoid writ- ing code for anti-forgery tokens, you must make sure an attacker can’t authenti- cate to the action using a cookie enabled by the server. If you have normal ASP. NET Forms authentication enabled, that’s being done at the read more..

  • Page - 486

    450 ❘ CHAPTER 15 EXTENDING MVC Implementing an authentication fi lter involves two methods, OnAuthentication and OnAuthenticationChallenge . The OnAuthentication method in the sample does some fairly low- level work to handle the details of the HTTP Basic protocol. If you’re curious about the protocol details, see section 2 of RFC 2617 read more..

  • Page - 487

    Extending Controllers ❘ 451 CurrentPrincipal , HttpContext.Current.User , and Controller.User . If an authentication fi lter wants to combine its result with a previous authentication fi lter, it can examine the current Principal property on AuthenticationContext before overriding it. Was this kind of authentication attempted? Did authentication succeed? Do nothing Implementing read more..

  • Page - 488

    452 ❘ CHAPTER 15 EXTENDING MVC public ActionResult InnerResult { get; set; } public override void ExecuteResult(ControllerContext context) { InnerResult.ExecuteResult(context); var response = context.HttpContext.Response; if (response.StatusCode == 401) { read more..

  • Page - 489

    Extending Controllers ❘ 453 the pipeline runs normally, if another authentication fi lter short-circuits with an error, or if the same authentication fi lter instance short-circuits with an error. You’ll want to make sure your challenge result does the correct thing in all three cases. In our HTTP Basic sample implementation, we always read more..

  • Page - 490

    454 ❘ CHAPTER 15 EXTENDING MVC Authorization Filters A fi lter that wants to participate in authorization implements the IAuthorizationFilter interface. Authorization fi lters execute just after authentication fi lters. Because they run relatively early in the action pipeline, authorization fi lters are appropriately used for activities that read more..

  • Page - 491

    Extending Controllers ❘ 455 if (!filterContext.IsChildAction && response.ContentType == "text/html") response.Write( String.Format( "<h5>Action '{0} :: {1}', Execute: {2}ms, Result: {3}ms.</h5>", filterContext.RouteData.Values["controller"], read more..

  • Page - 492

    456 ❘ CHAPTER 15 EXTENDING MVC { get { return typeof(IExceptionFilter); } } } public static class FilterConfig { public static void RegisterGlobalFilters( GlobalFilterCollection filters) { filters.Add(new LogToDatabaseExceptionFilter()); } } [OverrideAllExceptionFilters] public ActionResult read more..

  • Page - 493

    Extending Controllers ❘ 457 one of them on your controller, you can add an attribute to override all action fi lters and then re-add attributes for the specifi c action fi lters you want to keep. NOTE If there are only fi ve types of fi lters you can override, why not just pro- vide fi ve fi lter override attributes out of read more..

  • Page - 494

    458 ❘ CHAPTER 15 EXTENDING MVC ➤ We wanted to enable good unit testing throughout the framework. By using action result classes, we enable developers to write simple unit tests that directly call action methods, and inspect the action result return values that result. Unit testing an action result’s parameters is much simpler than picking through the HTML that read more..

  • Page - 495

    Summary ❘ 459 views, you saw how to customize view engines to provide your own conventions about locating view fi les, as well as two variations of helper methods for generating HTML inside your views. Finally, you learned about controller extensibility through the use of action selectors, fi lters, and custom action result types, all read more..

  • Page - 496

    read more..

  • Page - 497

    Advanced Topics WHAT’S IN THIS CHAPTER? ➤ Using mobile support ➤ Understanding advanced Razor features ➤ Working with view engines ➤ Understanding and customizing scaffolding ➤ Working with tricky routing scenarios ➤ Customizing templates ➤ Using controllers in advanced scenarios In previous chapters in this book, we postponed discussing some of our read more..

  • Page - 498

    462 ❘ CHAPTER 16 ADVANCED TOPICS A variety of approaches exist for enhancing the mobile experience of your web application. In some cases, you just want to make some minor style changes on smaller display resolutions. In others you might want to completely change the visual appearance or content of some views. In the most read more..

  • Page - 499

    Mobile Support ❘ 463 Although, you can certainly build great web applications targeting widescreen, desktop displays (as you’ve seen in this book), mobile-friendly layouts are more than just supported in Bootstrap 3— they’re a fi rst-class concern. FIGURE 16-1 read more..

  • Page - 500

    464 ❘ CHAPTER 16 ADVANCED TOPICS Therefore, that an MVC 5 application fares a lot better in a mobile browser without additional work on your part, is no surprise, as shown in Figure 16-2. FIGURE 16-2 What’s immediately obvious is that the page in Figure 16-2 is intelligently scaled to the screen size of the mobile device. read more..

  • Page - 501

    Mobile Support ❘ 465 What might not be immediately obvious is that the page layout actually changes subtly at this smaller size to optimize for the new dimensions. For example, the header navigation is collapsed from fi ve separate text links to a single drop-down menu, as shown in Figure 16-3. FIGURE 16-3 Scrolling down further, you can read more..

  • Page - 502

    466 ❘ CHAPTER 16 ADVANCED TOPICS For example, form fi elds shown in the Register view (also visible in Figure 16-3) are appropriately sized for touch entry on a mobile device. These templates use adaptive rendering to automatically scale the page depending on page width. Note that I didn’t say that the application scales the page by read more..

  • Page - 503

    Mobile Support ❘ 467 A media query consists of a media type and zero or more expressions that check for the conditions of particular media features. Among the media features that can be used in media queries are ‘width,’ ‘height,’ and ‘color.’ By using media queries, presentations can be tailored to a specifi c range of output read more..

  • Page - 504

    468 ❘ CHAPTER 16 ADVANCED TOPICS FIGURE 16-4 For comparison, Figure 16-5 shows that same browser window resized to just over 768px. You can easily test this out without writing any code: Create a new MVC 5 project, run it, and resize the browser. Responsive Web Design with Bootstrap As you’ve seen, adaptive layout (using media queries to read more..

  • Page - 505

    Mobile Support ❘ 469 FIGURE 16-5 The Bootstrap 3 grid system is especially useful in managing complex layouts at varying screen sizes. It divides the screen width into twelve columns, then lets you specify how many columns a grid element should occupy depending on the screen width: ➤ Extra-small: <768px ➤ Small: >=768px ➤ read more..

  • Page - 506

    470 ❘ CHAPTER 16 ADVANCED TOPICS For example, the following HTML allocates six columns (half the grid width) per item on mobile devices, but only four columns (one-third of the grid width) per item on larger displays: <div class="row"> <div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div> <div class="col-xs-6 read more..

  • Page - 507

    Mobile Support ❘ 471 FIGURE 16-6 Layout and Partial View Support You can also create mobile versions of both layouts and partial view templates. If your Views\Shared folder contains both the _Layout.cshtml and tem- plates, by default the application will use during requests from mobile browsers and _Layout.cshtml read more..

  • Page - 508

    472 ❘ CHAPTER 16 ADVANCED TOPICS FIGURE 16-7 Custom Display Modes Additionally, you can register your own custom device modes that will be based on your own custom criteria. For example, to register a WinPhone device mode that would serve views ending read more..

  • Page - 509

    Advanced Razor ❘ 473 with .WinPhone.cshtml to Windows Phone devices, you would use the following code in the Application_Start method of your Global.asax : DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("WinPhone") { ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf ("Windows Phone OS", read more..

  • Page - 510

    474 ❘ CHAPTER 16 ADVANCED TOPICS The result is that you can write a method that accepts a Razor template as an argument value simply by making that argument be a Func<T, HelperResult> . Going back to the RenderSection example presented in the Layouts example in Chapter 3, let’s do just that: public static class RazorLayoutHelpers read more..

  • Page - 511

    Advanced Razor ❘ 475 Web.config fi le in the Views directory. The following section of Web.config contains the Razor confi guration: <system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> read more..

  • Page - 512

    476 ❘ CHAPTER 16 ADVANCED TOPICS NOTE To see this code as well as Layouts in action, use NuGet to install the Wrox.ProMvc5.Views.BasePageType package into a default ASP.NET MVC 5 project, as follows: Install-Package Wrox.ProMvc5.Views.BasePageType After installing this package, you must change the base page type within the Web.config fi le in read more..

  • Page - 513

    Advanced View Engines ❘ 477 in this chapter, the Controller base class contains a simple convenience method, named View , that returns a ViewResult . Under the hood, the ViewResult calls into the current view engine to render the view. Confi guring a View Engine As just mentioned, having alternative view engines registered for an application is read more..

  • Page - 514

    478 ❘ CHAPTER 16 ADVANCED TOPICS Finding a View The IViewEngine interface is the key interface to implement when building a custom view engine: public interface IViewEngine { ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache); ViewEngineResult FindView(ControllerContext controllerContext, string read more..

  • Page - 515

    Advanced View Engines ❘ 479 The View Itself The IView interface is the second interface you need to implement when implementing a custom view engine. Fortunately, it is quite simple, containing a single method: public interface IView { void Render(ViewContext viewContext, TextWriter writer); } Custom views are supplied with a ViewContext instance, which read more..

  • Page - 516

    480 ❘ CHAPTER 16 ADVANCED TOPICS PROPERT Y DESCRIPTION IsChildAction Boolean value indicating whether the action is being displayed as a result of a call to Html.Action or Html. RenderAction . ParentActionViewContext When IsChildAction is true , contains the ViewContext of this view’s parent view. Writer HtmlTextWriter to use for HTML helpers that don’t return strings read more..

  • Page - 517

    Advanced View Engines ❘ 481 Several third-party view engines are available at the time of this writing. Table 16-3 lists some of the more well-known view engines, but there are likely many others we’ve never heard of. TABLE 16-3: Alternative View Engines VIEW ENGINE DESCRIPTION Spark Spark ( is the brainchild of Louis read more..

  • Page - 518

    482 ❘ CHAPTER 16 ADVANCED TOPICS New View Engine or New ActionResult? We are often asked when someone should create a custom view engine as opposed to a new ActionResult type. For example, suppose that you want to return objects in a custom XML for- mat. Should you write a custom view engine or a new MyCustomXmlFormatActionResult ? The read more..

  • Page - 519

    Advanced Scaffolding ❘ 483 Customizing Scaffold Templates The default scaffolders generate code using the Text Template Transformation Toolkit, commonly referred to as T4. T4 is a code generation engine integrated with Visual Studio. As the name implies, the template format is text based, so templates are relatively easy to edit. T4 templates read more..

  • Page - 520

    484 ❘ CHAPTER 16 ADVANCED TOPICS FIGURE 16-9 FIGURE 16-10 read more..

  • Page - 521

    Advanced Scaffolding ❘ 485 Adding a new scaffold template is as simple as copying and pasting one of the existing templates, renaming it to whatever you want to show up in the dialog, and modifying the template code. For instance, if you commonly show a delete success view after a delete action, you can copy one of the templates in read more..

  • Page - 522

    486 ❘ CHAPTER 16 ADVANCED TOPICS Item dialog. This feature is even more powerful when you remember that the ASP.NET Scaffolding system works in any ASP.NET project. As you would expect, this level of customization requires you to put in some effort. A full walk- through is available on the .NET Web Development and Tools blog: read more..

  • Page - 523

    Advanced Routing ❘ 487 This project is also available as a NuGet package appropriately named RouteMagic. RouteMagic is a pet project of Phil Haack, one of the authors of this book, and provides useful extensions to ASP. NET Routing that go above and beyond what’s included “in the box.” One useful extension included in the RouteMagic read more..

  • Page - 524

    488 ❘ CHAPTER 16 ADVANCED TOPICS FIGURE 16-12 FIGURE 16-13 Setting the Build Action to “Content” in tentionally excludes the Routes.cs fi le from build-time compilation because we want it to be compiled dynamically at run time. Following is the code for Routes.cs . (Don’t worry about entering this code manually; it’s provided as a read more..

  • Page - 525

    Advanced Routing ❘ 489 using System.Web.Mvc; using System.Web.Routing; using RouteMagic; public class Routes : IRouteRegistrar { public void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: read more..

  • Page - 526

    490 ❘ CHAPTER 16 ADVANCED TOPICS With this in place, you can now change routes within the Routes.cs fi le in the App_Start directory after you’ve deployed the application without recompiling your application. To see this in action, you can run the application and notice the standard home page comes up. Then, without stopping the read more..

  • Page - 527

    Advanced Routing ❘ 491 Here’s the code that RouteMagic uses to add a cache dependency pointing to Routes.cs and a callback method that will reload the routes when Routes.cs is changed: using System; using System.Web.Compilation; using System.Web.Routing; using RouteMagic.Internals; namespace RouteMagic { public static class RouteRegistrationExtensions { read more..

  • Page - 528

    492 ❘ CHAPTER 16 ADVANCED TOPICS ADVANCED TEMPLATES Chapter 5 introduced templated helpers. The templated helpers are the subset of HTML helpers including EditorFor and DisplayFor , and they are called the templated helpers because they ren- der HTML using model metadata and templates. To jog your memory, imagine the following Price property read more..

  • Page - 529

    Advanced Templates ❘ 493 based on the type name of the value it is rendering. When you ask EditorFor to render a property of type System.Boolean (like IsDiscounted ), it uses the template named Boolean . When you ask EditorFor to render a property of type System.Decimal (like Price ), it uses the template named Decimal . read more..

  • Page - 530

    494 ❘ CHAPTER 16 ADVANCED TOPICS The TemplateInfo property of ViewData gives you access to a FormattedModelValue property. The value of this property is either the properly formatted model value as a string (based on the format strings in ModelMetadata ) or the original raw model value (if there is no format string speci- fi ed). read more..

  • Page - 531

    Advanced Templates ❘ 495 Template Selection It should be clear that if the framework selects a template based on a model’s type name, then a decimal property renders with the Decimal template. But what about types that don’t have a default template defi ned in System.Web.Mvc.Html.DefaultEditorTemplates —types such as Int32 and DateTime ? read more..

  • Page - 532

    496 ❘ CHAPTER 16 ADVANCED TOPICS @Html.Editor(prop.PropertyName) @Html.ValidationMessage(prop.PropertyName, "*") </div> } } } @functions { bool ShouldShow(ModelMetadata metadata) { return metadata.ShowForEdit read more..

  • Page - 533

    Advanced Templates ❘ 497 FIGURE 16-14 read more..

  • Page - 534

    498 ❘ CHAPTER 16 ADVANCED TOPICS You could place the preceding code inside a fi le named DateTime.cshtml , and place the fi le inside the Shared\EditorTemplates folder. Then, all you need to add a Datepicker to every DateTime property editor is a small bit of client script (be sure to include the jQuery UI scripts and stylesheets as you read more..

  • Page - 535

    Advanced Controllers ❘ 499 and fl exibility. When building software with these focuses, leveraging abstraction as much as pos- sible by using interfaces is important. For a class to be a controller in ASP.NET MVC, it must at minimum implement the IController interface, and by convention the name of the class must end with the suffi x read more..

  • Page - 536

    500 ❘ CHAPTER 16 ADVANCED TOPICS PRODUCT TEAM ASIDE Back in the early days the ASP.NET MVC product team debated removing the IController interface completely. Developers who wanted to implement that inter- face could use their own implementation of MvcHandler instead, which decidedly handles a lot of the core execution mechanics based on the request read more..

  • Page - 537

    Advanced Controllers ❘ 501 IController interface. The Controller class is intended to serve as the base class for all control- lers because it provides a lot of nice behaviors to controllers that derive from it. Figure 16-15 shows the relationship between IController , ControllerBase , the Controller abstract base class, and the two controllers that read more..

  • Page - 538

    502 ❘ CHAPTER 16 ADVANCED TOPICS Action Methods All public methods of a class that derive from Controller are action methods, which are potentially callable via an HTTP request. Rather than one monolithic implementation of Execute , you can fac- tor your controller into action methods, each of which responds to a specifi c user input. PRODUCT TEAM read more..

  • Page - 539

    Advanced Controllers ❘ 503 Notice that the class contains a single method, ExecuteResult . If you’re familiar with the Command Pattern, this should look familiar to you. Action results represent commands that your action method wants the framework to perform on its behalf. Action results generally handle framework-level work, while the action method read more..

  • Page - 540

    504 ❘ CHAPTER 16 ADVANCED TOPICS Notice that it returns the result of a call to the View method. The Controller class contains sev- eral convenience methods for returning ActionResult instances. These methods are intended to help make action method implementations a bit more readable and declarative. Instead of creating new instances of action read more..

  • Page - 541

    Advanced Controllers ❘ 505 METHOD DESCRIPTION View Returns a ViewResult , which renders the view to the response. PartialView Returns a PartialViewResult , which renders a partial view to the response. Content Returns a ContentResult , which writes the specifi ed content (string) to the response. File Returns a class that derives from FileResult , which writes binary content to read more..

  • Page - 542

    506 ❘ CHAPTER 16 ADVANCED TOPICS ACTIONRESULT T YPE DESCRIPTION HttpUnauthorizedResult Derives from HttpStatusCodeResult . Returns an HTTP 401 response code to the client, indicating that the requestor does not have authorization to the resource at the requested URL. JavaScriptResult Used to execute JavaScript code immediately on the client sent from the server. JsonResult read more..

  • Page - 543

    Advanced Controllers ❘ 507 Note that FileResult is an abstract base class for three different fi le result types: ➤ FilePathResult ➤ FileContentResult ➤ FileStreamResult Usage typically follows the factory pattern in which the specifi c type returned depends on which overload of the File method (discussed later) is called. read more..

  • Page - 544

    508 ❘ CHAPTER 16 ADVANCED TOPICS This would be called by the following code: <%: Ajax.ActionLink("click", "DoSomething", new AjaxOptions()) %> <div id="some-div"></div> This assumes that you’ve referenced the Ajax libraries and jQuery. JsonResult The JsonResult uses the JavaScriptSerializer class to serialize its read more..

  • Page - 545

    Advanced Controllers ❘ 509 approach is that you won’t inadvertently serialize data you don’t want the client to see, such as any internal product codes, stock quantity, supplier information, and so forth. RedirectResult The RedirectResult performs an HTTP redirect to the specifi ed URL (set via the Url property). Internally, this result read more..

  • Page - 546

    510 ❘ CHAPTER 16 ADVANCED TOPICS To highlight this point, consider a Distance method that calculates the distance between two points. This action could write directly to the response — as shown in the fi rst controller actions in Chapter 2, in the section titled “Writing Your First (Outrageously Simple) Controller.” However, an read more..

  • Page - 547

    Advanced Controllers ❘ 511 NOTE The code to create a ContentResult instance is encapsulated in a virtual method on the action invoker called CreateActionResult . For those who want to return a different implicit action result type, you can write a customer action invoker that derives from ControllerActionInvoker and override that read more..

  • Page - 548

    512 ❘ CHAPTER 16 ADVANCED TOPICS Routing adds the value list with a key of action to the route values dictionary. At this point within the request, an action is just a string extracted from the URL; it is not a method. The string represents the name of the action that should handle this request. Though it may commonly read more..

  • Page - 549

    Advanced Controllers ❘ 513 This attribute is not required for an action method. There is an implicit rule that the name of the action method serves as the action name if this attribute is not applied. ActionSelectorAttribute You’re not done matching the action to a method yet. After you’ve identifi ed all methods of the Controller read more..

  • Page - 550

    514 ❘ CHAPTER 16 ADVANCED TOPICS [HttpPost] public ActionResult Edit(string id, FormCollection form) { //Save the item and redirect… } When a POST request for /home/edit is received, the action invoker creates a list of all methods of the controller that match the edit action name. In this case, you would end up with a list of two read more..

  • Page - 551

    Advanced Controllers ❘ 515 MVC allows the override for POST requests only. The framework will look for the overridden verb fi rst from the HTTP headers, then from POST values, and, fi nally, from query string values. Invoking Actions Next the invoker uses the model binder (discussed in depth in Chapter 4, in the “Model Binding” read more..

  • Page - 552

    516 ❘ CHAPTER 16 ADVANCED TOPICS Now consider an action that makes a network call as part of its execution, and consider that the network call might take two seconds to complete. From the site visitor’s point of view, the server takes about two seconds to respond to his or her request, if you take into account a little bit of read more..

  • Page - 553

    Advanced Controllers ❘ 517 THREAD A Asynchronous request timeline OnAuthorization() OnActionExecuting() action method OnActionExecuted() OnResultExecuting() action result OnResultExecuted() THREAD B FIGURE 16-17 Choosing Synchronous versus Asynchronous Pipelines The following are some guidelines for deciding whether to use synchronous or asynchronous pipe- lines. Note that these are just read more..

  • Page - 554

    518 ❘ CHAPTER 16 ADVANCED TOPICS For example, consider a portal site that displays news for a given area. The news in this example is provided via a GetNews() method that involves a network call that could be long running. A typical synchronous action might look like this: public class PortalController : Controller { public read more..

  • Page - 555

    Advanced Controllers ❘ 519 SportsService sportsService = new SportsService(); PortalViewModel model = new PortalViewModel { News = newsService.GetNews(city), Weather = weatherService.GetWeather(city), Sports = sportsService.GetScores(city) }; return View(model); read more..

  • Page - 556

    520 ❘ CHAPTER 16 ADVANCED TOPICS In both of the preceding examples, the URL to access the action is /Portal/Index?city=Seattle (or /Portal?city=Seattle , using the default route), and the view page name is Index.cshtml (because the action name is Index). This is a classic example where async is used not only for effi ciency, but for read more..

  • Page - 557

    Real-World ASP.NET MVC: Building the Website —by Phil Haack and Jon Galloway WHAT’S IN THIS CHAPTER? ➤ Source code for the NuGet gallery ➤ Working with WebActivator ➤ How to use ASP.NET Dynamic Data ➤ Using the Error Logging Module and Handler ➤ Profi ling basics ➤ Accessing data with Code First ➤ Code First migrations ➤ Octopus read more..

  • Page - 558

    522 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE This chapter reviews a real-world application, warts and all, built with ASP.NET MVC. In fact, if you read Chapter 10, you are probably already familiar with the application. It is the NuGet Gallery. You can visit it at to get a feeling for the read more..

  • Page - 559

    May the Source Be with You ❘ 523 When you open the solution in Visual Studio, you’ll notice that there are four function areas: Backend, Frontend, Operations, and Core (in the root of the application). These four areas are com- prised of a total of seven projects, as shown in Figure 17-1. FIGURE 17-1 NOTE The two Facts projects read more..

  • Page - 560

    524 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE We explained why the solution contained only two projects: Many ASP.NET MVC applications prematurely split the solution into multiple different class libraries. One reason this happens is a holdover from the very fi rst version of ASP.NET, where a website could not be read more..

  • Page - 561

    May the Source Be with You ❘ 525 double the amount of packages you’ll see in a File ➪ New MVC application. That isn’t an accurate number of separate products in use because some products are split into multiple NuGet packages, but it gives an indication of how extensively third-party libraries are used. Covering all these prod- read more..

  • Page - 562

    526 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE WEBACTIVATOR Many third-party libraries require more than a simple assembly reference to be useful. They some- times need the application to run a bit of confi guration code when the application starts up. In the past, this meant you would need to copy and paste a bit of read more..

  • Page - 563

    ASP.NET Dynamic Data ❘ 527 ASP.NET DYNAMIC DATA ASP.NET Dynamic Data is a feature that’s often been ignored by ASP.NET MVC developers because it’s a Web Forms feature. True, it is built on top of Web Forms, but that’s really just an implementation detail. ASP.NET MVC and Web Forms are all ASP.NET applications and can be intermingled in read more..

  • Page - 564


  • Page - 565

    ASP.NET Dynamic Data ❘ 529 FIGURE 17-5 read more..

  • Page - 566

    530 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE FIGURE 17-6 WARNING Dynamic Data isn’t easy to set up on EF6 and MVC5. Adding Dynamic Data to an existing ASP.NET MVC application takes a bit of work, especially with EF6, so it’s beyond the scope of this book. Using a sample Dynamic Data application and the read more..

  • Page - 567

    Exception Logging ❘ 531 Installing the main elmah package works great for a demo, but it doesn’t work for a real site because the exception log is stored in memory, which doesn’t persist if the application is restarted. Fortunately, ELMAH includes packages for most of the major database vendors as well as one that stores items in read more..

  • Page - 568

    532 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE Now you can visit /elmah.axd in your site to see logged unhandled exceptions. If you still can’t access elmah.axd , make sure you added your user to the Admins role as previously explained. You can change the location by modifying the handler path in web.config read more..

  • Page - 569

    Profi ling ❘ 533 FIGURE 17-8 FIGURE 17-9 read more..

  • Page - 570

    534 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE FIGURE 17-10 This causes the Glimpse panel to expand and show much more detailed information about the request. Clicking the Timeline tab shows detailed timing information for each step on the request (see Figure 17-11). FIGURE 17-11 The details on the Timeline tab might remind you read more..

  • Page - 571

    Data Access ❘ 535 of detailed performance information available for every page request against your production envi- ronment is quite powerful (remember, only for Admin users). Code that uses Entity Framework, an ORM, can make it diffi cult to know exactly what SQL is generated and run against the database. The SQL tab exposes that read more..

  • Page - 572

    536 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE Code First is heavily convention-based and requires very little confi guration by default. Of course, developers tend to be an opinionated lot with strong personal preferences and need to customize everything they touch, and the NuGet team is no different. We read more..

  • Page - 573

    EF Code–Based Migrations ❘ 537 Although I don’t cover all the details of migrations here, I do cover some of the ways we make use of migrations. Expand the Migrations folder to see the list of migrations included in the NuGet Gallery, as shown in Figure 17-13. The migrations are named with a timestamp prefi x to ensure they read more..

  • Page - 574

    538 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE The one named 201110060711357_Initial.cs is the starting point. This fi le creates the initial set of tables. After that, each migration applies schema changes as we develop the site and make changes. You use the NuGet Package Manager Console to create migrations. For read more..

  • Page - 575

    Deployments with Octopus Deploy ❘ 539 Previously, the NuGet Gallery codebase ran migrations automatically every time you ran the site. This was done using a DbMigratorPostStart method in AppActivator.cs . The method has the following two lines that do the magic: var dbMigrator = new DbMigrator(new MigrationsConfiguration()); dbMigrator.Update(); MigrationsConfiguration is read more..

  • Page - 576

    540 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE FIGURE 17-14 AUTOMATED BROWSER TESTING WITH FLUENT AUTOMATION In addition to the xUnit-based unit test projects included in the main NuGet Gallery solution, the NuGet Gallery source contains a separate suite of functional tests (visible here: https://github read more..

  • Page - 577

    Other Useful NuGet Packages ❘ 541 string registerSignIn = "a:contains('Register / Sign in')"; string signOut = "a:contains('Sign out')"; string expectedUserName = "a:contains('NugetTestAccount')"; I.Click(registerSignIn); I.Expect.Url(x => x.LocalPath.Contains("LogOn")); read more..

  • Page - 578

    542 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE var jobs = new IJob[] { new UpdateStatisticsJob(TimeSpan.FromSeconds(10), () => new EntitiesContext(), timeout: TimeSpan.FromMinutes(5)), new WorkItemCleanupJob(TimeSpan.FromDays(1), () => new EntitiesContext(), timeout: TimeSpan.FromDays(4)), read more..

  • Page - 579

    Other Useful NuGet Packages ❘ 543 interface with Lucene. Also take a look at the LuceneIndexingJob , which is a WebBackgrounder job scheduled to run every 10 minutes. Recently, this per-server Lucene.NET search functionality was replaced by a dedicated search service (still running on Lucene.NET). This dedicated search service can maintain a much read more..

  • Page - 580

    544 ❘ CHAPTER 17 REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE The second binding does the same thing, but the InSingletonScope ensures that there’s only one instance of FormsAuthenticationService for the whole application. If a service holds onto any request state, or requires request state in its constructor, make sure to use request read more..

  • Page - 581

    ASP.NET MVC 5.1 —by Jon Galloway WHAT’S IN THIS CHAPTER? ➤ What’s in ASP.NET MVC 5.1 and Visual Studio 2013 Update 2 ➤ Facts about Enum support ➤ How to perform Attribute Routing with Custom Constraints ➤ Working with Bootstrap and JavaScript enhancements This appendix describes some of the top features in MVC 5.1, and how you can start using read more..

  • Page - 582

    546 ❘ APPENDIX ASP.NET MVC 5.1 The top MVC 5.1 features in this release are as follows: ➤ Attribute Routing improvements ➤ Bootstrap support for editor templates ➤ Enum support in views ➤ Unobtrusive validation for MinLength /MaxLength attributes ➤ Supporting the ‘this’ context in Unobtrusive Ajax ➤ Various bug fi xes This release also includes read more..

  • Page - 583

    ASP.NET MVC 5.1 Release Description ❘ 547 needing to install anything that will affect your development environment, other projects you’re working on, your server environment, or other applications on your server. You don’t need to wait for your hosting provider to support ASP.NET MVC 5.1, ASP.NET Web API 2.1, or ASP.NET Web Pages 3.1—if they read more..

  • Page - 584

    548 ❘ APPENDIX ASP.NET MVC 5.1 FIGURE A-1 FIGURE A-2 read more..

  • Page - 585

    Enum Support in ASP.NET MVC Views ❘ 549 3. Because this is a throw-away project, you can just click Update All. If you’re upgrading a real project, I recommend reviewing the package updates before installing them. This is especially important for the JavaScript libraries, as the upgrade from jQuery 1.x to 2.x has some break- ing changes. Figure A-3 shows the read more..

  • Page - 586

    550 ❘ APPENDIX ASP.NET MVC 5.1 //I guess technically these are called honorifics public enum Salutation { [Display(Name = "Mr.")] Mr, [Display(Name = "Mrs.")] Mrs, [Display(Name = "Ms.")] Ms, [Display(Name read more..

  • Page - 587

    Enum Support in ASP.NET MVC Views ❘ 551 FIGURE A-4 FIGURE A-5 read more..

  • Page - 588

    552 ❘ APPENDIX ASP.NET MVC 5.1 You can update your application so that all Enum values are shown using the Enum view helpers by taking advantage of EditorTemplates and DisplayTemplates , as explained in the “Custom Templates” section of Chapter 16. You can fi nd examples of them in the Enum Sample on CodePlex: read more..

  • Page - 589

    Attribute Routing with Custom Constraints ❘ 553 FIGURE A-7 7. The Enum Sample referenced above also includes an EditorTemplate to display Enums using a radio button list rather than a dropdown. Use the override in Html.EditorFor to specify the EditorTemplate , like this: @Html.EditorFor(model => model.Salutation, templateName: "Enum-radio") Now all enum values read more..

  • Page - 590

    554 ❘ APPENDIX ASP.NET MVC 5.1 public interface IRouteConstraint { bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection); } Route Constraints in Attribute Routing One of the top new features in ASP.NET MVC 5 and Web API 2 is the addition of Attribute read more..

  • Page - 591

    Attribute Routing with Custom Constraints ❘ 555 && !string.IsNullOrWhiteSpace(value as string)) { string locale = value as string; if (isValid(locale)) { read more..

  • Page - 592

    556 ❘ APPENDIX ASP.NET MVC 5.1 } public override RouteValueDictionary Constraints { get { var constraints = new RouteValueDictionary(); constraints.Add("locale", read more..

  • Page - 593

    Attribute Routing with Custom Constraints ❘ 557 Before running this, you need to verify that you have Attribute Routes enabled in your RouteConfig : public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapMvcAttributeRoutes(); read more..

  • Page - 594

    558 ❘ APPENDIX ASP.NET MVC 5.1 logic on the entire route or context. One great example is using a custom attribute based on a user’s locale selection (set in a cookie, perhaps) or using a header. So, to recap: ➤ Previously, you could write custom route constraints using “Traditional” code-based rout- ing, but not in Attribute Routing. ➤ Previously, read more..

  • Page - 595

    Bootstrap and JavaScript Enhancements ❘ 559 In the 5.1 release, you can now pass HTML attributes as an additional parameter to Html .EditorFor . This allows you to apply custom Bootstrap styles while retaining all the advantages of templated editors. Here’s an example of why that’s useful. In the “Enum Support in ASP.NET MVC Views” read more..

  • Page - 596

    560 ❘ APPENDIX ASP.NET MVC 5.1 You’ll notice some subtle improvements, like the focus highlight on the FirstName fi eld, nicer text- box size and validation layout for Age , and so on. These are just simple things with a very basic model, but they you give a quick idea of the various improvements. Also nice is that you can read more..

  • Page - 597

    Bootstrap and JavaScript Enhancements ❘ 561 Sir, Lady, Lord } That gives you the exact same output as shown in Figure A-12. What’s cool is that the EditorFor method passed the form-control class to each element in the form, so each input tag got the form- control class. That means that I could apply read more..

  • Page - 598

    562 ❘ APPENDIX ASP.NET MVC 5.1 FIGURE A-13 Three Small but Useful Fixes to MVC Ajax Support MVC 5.1 includes a few bug fi xes for MVC Ajax forms: ➤ Support “this” context for Ajax actions/forms ➤ Unobtrusive.Ajax no longer interferes with the cancel convention on validation ➤ LoadingElementDuration previously didn’t work; this is now corrected read more..

  • Page - 599

    Summary ❘ 563 } $('#cart-total').text(data.CartTotal); $('#update-message').text(data.Message); $('#cart-status') read more..

  • Page - 600

    read more..

  • Page - 601

    Index read more..

  • Page - 602

    read more..

  • Page - 603

    567 INDEX Numbers & Sy mbols @ sign, 64–66 @@ sign, 66 {} (curly braces), 68 ~ (tilde), 55, 132 3A (Arrange, Act, Assert), 411–412 A About method, HomeController , 53 About.cshtml fi le, 53 Abstractions.dll assembly, 418 AcceptVerbsAttribute attribute, 513–514 AccountController class, 39, 165, 193 AuthorizeAttribute , 167–169 global authorization, read more..

  • Page - 604

    568 ajax method – ASP.NET Web API selectors, 215–217 using in MVC applications, 219–225 validation, 233–236 writing custom scripts, 221–222 partial view updates, 73–74 performance optimization, 253–255 unobtrusive, 225–226 web.config settings, 234–235 ajax method, 250–251 AlbumList package, 57 AllowAnonymous attribute, 170–172, 349 alpha inline constraint, read more..

  • Page - 605

    569 asynchronous controller actions – Code Analysis Tool .NET ProductsController example, 352–354 tracing applications, 352 writing an API controller, 335–342 asynchronous controller actions, 515–520 at (@) sign, 64–66 atTheMovies.js fi le, 365, 375–376 attribute routes, 14, 260–271. See also routing catch-all parameter, 284–285 combining with traditional read more..

  • Page - 606

    570 code blocks – .cshtml fi les code blocks, 68–70 code delimeter, escaping, 70 code expressions, 64–66, 68–69 Code First, 83, 174, 535–539 code-focused templating for HTML generation, 6 command-query responsibility segregation (CQRS), 84 commenting out code, 70 Compare attribute, DataAnnotations , 145 complacency, 210 Conery, Rob, 402 Configuration.cs fi le, 362 read more..

  • Page - 607

    571 CSRF – description metadata element _DailyDeal.cshtml , 228–229 Edit.cshtml , 118–121, 139 Index.cshtml , 51–52, 71–72, 91–92, 222–223, 226 _Layout.cshtml , 62, 126, 219–220, 222, 226, 471 Login.cshtml , 233–236 Message.cshtml , 73 Mobile.cshtml , 9, 470–472 NotIndex.cshtml , 55 SiteLayout.cshtml , 70–72 _ViewStart.cshtml , 63, 73 WinPhone.cshtml , 473 CSRF read more..

  • Page - 608

    572 design patterns – fi lters design patterns, 385–395 dependency injection, 392–395 inversion of control, 386–388 service locator, 388–392 Details scaffold template, 62 DetailsController.js fi le, 374 directory structure, ASP.NET MVC applications, 24–27 Display attribute, DataAnnotations , 155–156 display modes, 9–10, 470–473 DisplayFor HTML helper, 91–92, read more..

  • Page - 609

    573 fl oat inline constraint – HTML helpers authorization fi lters, 349, 454 exception fi lters, 349, 455 override fi lters, 15–16, 448, 455–457 result fi lters, 454–455 float inline constraint, 267 Fluent Automation, 540–541 /fonts directory, 25 foreign key properties, 79, 83, 91, 93 FormContext property, ViewContext , 479 FormIdGenerator read more..

  • Page - 610

    574 Html5EditorTemplates package – install.ps1 script rendering helpers, 130–135 RenderPartial , 133 RouteLink , 131–132 strongly typed helpers, 126–127 templated helpers, 127–128 TextArea , 121 TextBox , 121 TextBoxFor , 127–128, 235–236 URL helpers, 132–135 ValidationMessage , 123–124 ValidationMessageFor , 120 ValidationSummary , 118 Html5EditorTemplates package, 498 HTTP 302 read more..

  • Page - 611

    575 installing – JSVE installing AngularJS, 359–361 ASP.NET MVC 5, 16 NuGet packages, 303–307 $installPath , NuGet PowerShell script parameter, 320 int inline constraint, 267 interception, 182, 295, 395 InternalServerError method, ApiController , 341 inversion of control (IoC) design pattern, 386–388 IoC (inversion of control) design pattern, 386–388 IRouteConstraint read more..

  • Page - 612

    576 Katana project – model binding K Katana project, 344, 345 L Label HTML helper, 121–122, 127 LabelFor HTML helper, 120 language metadata element, NuGet, 317 _Layout.cshtml fi le, 62, 126, 219–220, 222, 226, 471 layouts default changes in MVC 5, 72 in Razor, 70–72 lazy loading, 89–90 length inline constraint, 267 licenseUrl metadata read more..

  • Page - 613

    577 Model-View-Presenter – parameter binding system, 347–348 security, 105 validation and, 147–148 value providers, 104, 347–348, 430–431 Model-View-Presenter (MVP) pattern, 32 ModelMetadataProvider service, Web API, 403 models. See also model binding creating with model binders, 431–436 MVC Music Store example, 76–80 describing with metadata, 436–438 read more..

  • Page - 614

    578 Null Object pattern – POST requests as real-world example automated browser testing, 540–541 data access, 535–536 deployments, 539–540 Entity Framework code-based migrations, 536–539 exception logging, 530–532 profi ling, 532–536 source code, 522–525 publishing to, 325–327 Null Object pattern, 506, 510 Nustache view engine, 481 O OAuth read more..

  • Page - 615

    579 Product.cs fi le – route defaults model binding and, 103–105 overrides, 514–515 Product.cs fi le, 352 ProductsController , 352–354 profi ling, 532–535 progressive enhancement, 218–219 $project , NuGet PowerShell script parameter, 320 Project_Readme.html fi le, 24 projectUrl metadata element, NuGet, 316 publishing NuGet packages, 325–332 pull requests, 10 Q read more..

  • Page - 616

    580 route values – security route values attribute routes, 262–263 traditional routes, 273–274 RouteBase class, 288–289, 421 RouteCollection class, 288–289, 346, 421, 490–491 RouteConfig.cs fi le, 261, 271, 489, 554 RouteData property RequestContext , 295 ViewContext , 479 RouteLink HTML helper, 131–132 RouteMagic, 486–487 RouteUrlExpressionBuilder , 297 read more..

  • Page - 617

    581 self-validating model – System.Web.Mvc.Routing.Constraints namespace defense in depth strategy, 211 error reporting, 207–209 logins external, 175–182 redirection process, 168 requiring, 162–172 model binding, 105 open redirection attacks, 168, 202–207 over-posting attacks, 105, 107, 200–202 permissions management, 173 resources, 210–211 role membership, requiring, 172–174 read more..

  • Page - 618

    582 System.Web.Optimization namespace – validation System.Web.Optimization namespace, 254 System.Web.Routing namespace, 296 System.Web.UI namespace, 2, 429 T T4 (Text Template Transformation Toolkit) templates, 63, 483–485 tags metadata element, NuGet, 316 TAP (Task-based Asynchronous Pattern), 515, 517–518 Task Parallel Library, 515 Task-based Asynchronous Pattern (TAP), 515, read more..

  • Page - 619

    583 ValidationContext object – vNext custom validation, 150–155, 236–241 happy path, 102 jQuery validation, 233–236 and model binding, 147–148 and model state, 148 MVC 5.1, 561–562 sad path, 102–103 testing validators, 423–427 ValidationContext object, 425–427 ValidationMessage HTML helper, 123–124 ValidationMessageFor HTML helper, 120 ValidationSummary HTML read more..

  • Page - 620

    584 Wake – yellow screen of death W Wake, William C., 411 Walther, Stephen, 288 weakly typed service locators, 389–392 Web API, 333–354 adding routes, 346–347 ASP.NET MVC 4, 7–9 binding parameters, 347–348 confi guring, 342–346 defi ning, 334 enabling dependency injection, 350 exploring APIs programmatically, 350–351 fi ltering requests, 349–350 read more..

Write Your Review