ASP.NET Core in Action, Third Edition-9781633438620.pdf
Document Details
Uploaded by EquitableKnowledge
Tags
Full Transcript
inside front cover Praise for the Second Edition One of the greatest and most complete books about ASP.NET Core! —Delcoigne Vincent, Wavenet Fantastic book. The topics are explained clearly and thoroughly. It’s well written and researched. If you want a thorough understanding of ASP.NET Core,...
inside front cover Praise for the Second Edition One of the greatest and most complete books about ASP.NET Core! —Delcoigne Vincent, Wavenet Fantastic book. The topics are explained clearly and thoroughly. It’s well written and researched. If you want a thorough understanding of ASP.NET Core, this is where you need to start. —Luis Moux, EMO A comprehensive training and reference for ASP.NET Core with a touch of history of the.NET realm for.NET newcomers as well as.NET seniors. —Jean-François Morin, Laval University The most comprehensive ASP.NET Core book on the market. It covers just about everything you need to learn to quickly become productive in the often-confusing and fast-changing world of.NET Core. —Filip Wojcieszyn, Sonova AG One of the best books to learn the ins and outs of ASP.NET Core with confidence. —Raushan Jha, Microsoft Includes comprehensive information that prepares you to deliver robust and reliable real industry-standard applications. —Daniel Vásquez, RWS Excellent book with a thorough explanation of basic concepts and lots of tips for best practices. Highly recommended. —Ruben Vandeginste, PeopleWare Andrew Lock provides excellent insight into how to use ASP.NET Core. He provides clear, in-depth practical examples to solidify concepts described throughout the book. This book is a must have for.NET developers. —Foster Haines, Foster’s Website Company ASP.NET Core in Action Third Edition Andrew Lock To comment go to liveBook Manning Shelter Island For more information on this and other Manning titles go to www.manning.com Copyright For online information and ordering of these and other Manning books, please visit www.manning.com. The publisher offers discounts on these books when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Email: [email protected] ©2023 by Manning Publications Co. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. ♾ Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine. Manning Publications Co. 20 Baldwin Road Technical PO Box 761 Shelter Island, NY 11964 Development editor: Marina Michaels Technical editor: Filip Wojcieszyn Review editor: Adriana Sabo Production editor: Kathleen Rossland Copy editor: Keir Simpson Proofreader: Jason Everett Technical proofreader: Tanya Wilke Typesetter: Gordan Salinović Cover designer: Marija Tudor ISBN: 9781633438620 contents front matter preface acknowledgments about this book about the author about the cover illustration 1 Getting started with ASP.NET Core 1.1 What is ASP.NET Core? 1.2 What types of applications can you build? 1.3 Choosing ASP.NET Core 1.4 How does ASP.NET Core work? How does an HTTP web request work? How does ASP.NET Core process a request? 1.5 What you’ll learn in this book Part 1 Getting started with minimal APIs 2 Understanding ASP.NET Core 2.1 Using a web framework 2.2 Why ASP.NET Core was created 2.3 Understanding the many paradigms of ASP.NET Core 2.4 When to choose ASP.NET Core If you’re new to.NET development If you’re a.NET Framework developer creating a new application Converting an existing ASP.NET application to ASP.NET Core 3 Your first application 3.1 A brief overview of an ASP.NET Core application 3.2 Creating your first ASP.NET Core application Using a template to get started Building the application 3.3 Running the web application 3.4 Understanding the project layout 3.5 The.csproj project file: Declaring your dependencies 3.6 Program.cs file: Defining your application 3.7 Adding functionality to your application Adding and configuring services Defining how requests are handled with middleware and endpoints 4 Handling requests with the middleware pipeline 4.1 Defining middleware 4.2 Combining middleware in a pipeline Simple pipeline scenario 1: A holding page Simple pipeline scenario 2: Handling static files Simple pipeline scenario 3: A minimal API application 4.3 Handling errors using middleware Viewing exceptions in development: DeveloperExceptionPage Handling exceptions in production: ExceptionHandlerMiddleware 5 Creating a JSON API with minimal APIs 5.1 What is an HTTP API, and when should you use one? 5.2 Defining minimal API endpoints Extracting values from the URL with routing Mapping verbs to endpoints Defining route handlers with functions 5.3 Generating responses with IResult Returning status codes with Results and TypedResults Returning useful errors with Problem Details Converting all your responses to Problem Details Returning other data types 5.4 Running common code with endpoint filters Adding multiple filters to an endpoint Filters or middleware: Which should you choose? Generalizing your endpoint filters Implementing the IEndpointFilter interface 5.5 Organizing your APIs with route groups 6 Mapping URLs to endpoints using routing 6.1 What is routing? 6.2 Endpoint routing in ASP.NET Core 6.3 Exploring the route template syntax Working with parameters and literal segments Using optional and default values Adding additional constraints to route parameters Matching arbitrary URLs with the catch-all parameter 6.4 Generating URLs from route parameters Generating URLs for a minimal API endpoint with LinkGenerator Generating URLs with IResults Controlling your generated URLs with RouteOptions 7 Model binding and validation in minimal APIs 7.1 Extracting values from a request with model binding 7.2 Binding simple types to a request 7.3 Binding complex types to the JSON body 7.4 Arrays: Simple types or complex types? 7.5 Making parameters optional with nullables 7.6 Binding services and special types Injecting well-known types Injecting services Binding file uploads with IFormFile and IFormFileCollection 7.7 Custom binding with BindAsync 7.8 Choosing a binding source 7.9 Simplifying handlers with AsParameters 7.10 Handling user input with model validation The need for validation Using DataAnnotations attributes for validation Adding a validation filter to your minimal APIs Part 2 Building complete applications 8 An introduction to dependency injection 8.1 Understanding the benefits of dependency injection 8.2 Creating loosely coupled code 8.3 Using dependency injection in ASP.NET Core 8.4 Adding ASP.NET Core framework services to the container 8.5 Using services from the DI container 9 Registering services with dependency injection 9.1 Registering custom services with the DI container 9.2 Registering services using objects and lambdas 9.3 Registering a service in the container multiple times Injecting multiple implementations of an interface Injecting a single implementation when multiple services are registered Conditionally registering services using TryAdd 9.4 Understanding lifetimes: When are services created? Transient: Everyone is unique Scoped: Let’s stick together Singleton: There can be only one Keeping an eye out for captive dependencies 9.5 Resolving scoped services outside a request 10 Configuring an ASP.NET Core application 10.1 Introducing the ASP.NET Core configuration model 10.2 Building a configuration object for your app Adding a configuration provider in Program.cs Using multiple providers to override configuration values Storing configuration secrets safely Reloading configuration values when they change 10.3 Using strongly typed settings with the options pattern Introducing the IOptions interface Reloading strongly typed options with IOptionsSnapshot Designing your options classes for automatic binding Binding strongly typed settings without the IOptions interface 10.4 Configuring an application for multiple environments Identifying the hosting environment Loading environment-specific configuration files Setting the hosting environment 11 Documenting APIs with OpenAPI 11.1 Adding an OpenAPI description to your app 11.2 Testing your APIs with Swagger UI 11.3 Adding metadata to your minimal APIs 11.4 Generating strongly typed clients with NSwag Generating a client using Visual Studio Generating a client using the.NET Global tool Using a generated client to call your API Customizing the generated code Refreshing the OpenAPI description 11.5 Adding descriptions and summaries to your endpoints Using fluent methods to add descriptions Using attributes to add metadata Using XML documentation comments to add metadata 11.6 Knowing the limitations of OpenAPI Not all APIs can be described by OpenAPI Generated code is opinionated Tooling often lags the specification 12 Saving data with Entity Framework Core 12.1 Introducing Entity Framework Core What is EF Core? Why use an object-relational mapper? When should you choose EF Core? Mapping a database to your application code 12.2 Adding EF Core to an application Choosing a database provider and installing EF Core Building a data model Registering a data context 12.3 Managing changes with migrations Creating your first migration Adding a second migration 12.4 Querying data from and saving data to the database Creating a record Loading a list of records Loading a single record Updating a model with changes 12.5 Using EF Core in production applications Part 3 Generating HTML with Razor Pages and MVC 13 Creating a website with Razor Pages 13.1 Your first Razor Pages application Using the Web Application template Adding and configuring services Generating HTML with Razor Pages Handling request logic with page models and handlers 13.2 Exploring a typical Razor Page 13.3 Understanding the MVC design pattern 13.4 Applying the MVC design pattern to Razor Pages Directing a request to a Razor Page and building a binding model Executing a handler using the application model Building HTML using the view model Putting it all together: A complete Razor Page request 14 Mapping URLs to Razor Pages using routing 14.1 Routing in ASP.NET Core 14.2 Convention-based routing vs. explicit routing 14.3 Routing requests to Razor Pages 14.4 Customizing Razor Page route templates Adding a segment to a Razor Page route template Replacing a Razor Page route template completely 14.5 enerating URLs for Razor Pages Generating URLs for a Razor Page Generating URLs for an MVC controller Generating URLs with LinkGenerator 14.6 Customizing conventions with Razor Pages 15 Generating responses with page handlers in Razor Pages 15.1 Razor Pages and page handlers 15.2 Selecting a page handler to invoke 15.3 Accepting parameters to page handlers 15.4 Returning IActionResult responses PageResult and RedirectToPageResult NotFoundResult and StatusCodeResult 15.5 Handler status codes with StatusCodePagesMiddleware 16 Binding and validating requests with Razor Pages 16.1 Understanding the models in Razor Pages and MVC 16.2 From request to binding model: Making the request useful Binding simple types Binding complex types Choosing a binding source 16.3 Validating binding models Validation in Razor Pages Validating on the server for safety Validating on the client for user experience 16.4 Organizing your binding models in Razor Pages 17 Rendering HTML using Razor views 17.1 Views: Rendering the user interface 17.2 Creating Razor views Razor views and code-behind Introducing Razor templates Passing data to views 17.3 Creating dynamic web pages with Razor Using C# in Razor templates Adding loops and conditionals to Razor templates Rendering HTML with Raw 17.4 Layouts, partial views, and _ViewStart Using layouts for shared markup Overriding parent layouts using sections Using partial views to encapsulate markup Running code on every view with _ViewStart and _ViewImports 18 Building forms with Tag Helpers 18.1 Catering to editors with Tag Helpers 18.2 Creating forms using Tag Helpers The Form Tag Helper The Label Tag Helper The Input and Textarea Tag Helpers The Select Tag Helper The Validation Message and Validation Summary Tag Helpers 18.3 Generating links with the Anchor Tag Helper 18.4 Cache-busting with the Append Version Tag Helper 18.5 Using conditional markup with the Environment Tag Helper 19 Creating a website with MVC controllers 19.1 Razor Pages vs. MVC in ASP.NET Core 19.2 Your first MVC web application 19.3 Comparing an MVC controller with a Razor Page PageModel 19.4 Selecting a view from an MVC controller 19.5 Choosing between Razor Pages and MVC controllers The benefits of Razor Pages When to choose MVC controllers over Razor Pages 20 Creating an HTTP API using web API controllers 20.1 Creating your first web API project 20.2 Applying the MVC design pattern to a web API 20.3 Attribute routing: Linking action methods to URLs Combining route attributes to keep your route templates DRY Using token replacement to reduce duplication in attribute routing Handling HTTP verbs with attribute routing 20.4 Using common conventions with [ApiController] 20.5 Generating a response from a model Customizing the default formatters: Adding XML support Choosing a response format with content negotiation 20.6 Choosing between web API controllers and minimal APIs 21 The MVC and Razor Pages filter pipeline 21.1 Understanding the MVC filter pipeline 21.2 The Razor Pages filter pipeline 21.3 Filters or middleware: Which should you choose? 21.4 Creating a simple filter 21.5 Adding filters to your actions and Razor Pages 21.6 Understanding the order of filter execution The default scope execution order Overriding the default order of filter execution with IOrderedFilter 22 Creating custom MVC and Razor Page filters 22.1 Creating custom filters for your application Authorization filters: Protecting your APIs Resource filters: Short-circuiting your action methods Action filters: Customizing model binding and action results Exception filters: Custom exception handling for your action methods Result filters: Customizing action results before they execute Page filters: Customizing model binding for Razor Pages 22.2 Understanding pipeline short-circuiting 22.3 Using dependency injection with filter attributes Part 4 Securing and deploying your applications 23 Authentication: Adding users to your application with Identity 23.1 Introducing authentication and authorization Understanding users and claims in ASP.NET Core Authentication in ASP.NET Core: Services and middleware 23.2 What is ASP.NET Core Identity? 23.3 Creating a project that uses ASP.NET Core Identity Creating the project from a template Exploring the template in Solution Explorer The ASP.NET Core Identity data model Interacting with ASP.NET Core Identity 23.4 Adding ASP.NET Core Identity to an existing project Configuring the ASP.NET Core Identity services Updating the EF Core data model to support Identity Updating the Razor views to link to the Identity UI 23.5 Customizing a page in ASP.NET Core Identity’s default UI 23.6 Managing users: Adding custom data to users 24 Authorization: Securing your application 24.1 Introduction to authorization 24.2 Authorization in ASP.NET Core Preventing anonymous users from accessing your application Handling unauthorized requests 24.3 Using policies for claims-based authorization 24.4 Creating custom policies for authorization Requirements and handlers: The building blocks of a policy Creating a policy with a custom requirement and handler 24.5 Controlling access with resource-based authorization Manually authorizing requests with IAuthorizationService Creating a resource-based AuthorizationHandler 24.6 Hiding HTML elements from unauthorized users 25 Authentication and authorization for APIs 25.1 Authentication for APIs and distributed applications Extending authentication to multiple apps Centralizing authentication in an identity provider OpenID Connect and OAuth 2. 25.2 Understanding bearer token authentication 25.3 Adding JWT bearer authentication to minimal APIs 25.4 Using the user-jwts tool for local JWT testing Creating JWTs with the user-jwts tool Customizing your JWTs Managing your local JWTs 25.5 Describing your authentication requirements to OpenAPI 25.6 Applying authorization policies to minimal API endpoints 26 Monitoring and troubleshooting errors with logging 26.1 Using logging effectively in a production app Highlighting problems using custom log messages The ASP.NET Core logging abstractions 26.2 Adding log messages to your application Log level: How important is the log message? Log category: Which component created the log? Formatting messages and capturing parameter values 26.3 Controlling where logs are written using logging providers 26.4 Changing log verbosity with filtering 26.5 Structured logging: Creating searchable, useful logs Adding a structured logging provider to your app Using scopes to add properties to your logs 27 Publishing and deploying your application 27.1 Understanding the ASP.NET Core hosting model Running vs. publishing an ASP.NET Core app Choosing a deployment method for your application 27.2 Publishing your app to IIS Configuring IIS for ASP.NET Core Preparing and publishing your application to IIS 27.3 Hosting an application in Linux Running an ASP.NET Core app behind a reverse proxy in Linux Preparing your app for deployment to Linux 27.4 Configuring the URLs for your application 28 Adding HTTPS to an application 28.1 Why do I need HTTPS? 28.2 Using the ASP.NET Core HTTPS development certificates 28.3 Configuring Kestrel with a production HTTPS certificate 28.4 Enforcing HTTPS for your whole app Enforcing HTTPS with HTTP Strict Transport Security headers Redirecting from HTTP to HTTPS with HTTPS redirection middleware Rejecting HTTP requests in API applications 29 Improving your application’s security 29.1 Defending against cross-site scripting (XSS) attacks 29.2 Protecting from cross-site request forgery (CSRF) attacks 29.3 Calling your web APIs from other domains using CORS Understanding CORS and how it works Adding a global CORS policy to your whole app Adding CORS to specific endpoints with EnableCors metadata Configuring CORS policies 29.4 Exploring other attack vectors Detecting and avoiding open redirect attacks Avoiding SQL injection attacks with EF Core and parameterization Preventing insecure direct object references Protecting your users’ passwords and data Part 5 Going further with ASP.NET Core 30 Building ASP.NET Core apps with the generic host and Startup 30.1 Separating concerns between two files 30.2 The Program class: Building a Web Host 30.3 The Startup class: Configuring your application 30.4 Creating a custom IHostBuilder 30.5 Understanding the complexity of the generic host 30.6 Choosing between the generic host and minimal hosting 31 Advanced configuration of ASP.NET Core 31.1 Customizing your middleware pipeline Creating simple apps with the Run extension Branching middleware pipelines with the Map extension Adding to the pipeline with the Use extension Building a custom middleware component Converting middleware into endpoint routing endpoints 31.2 Using DI with OptionsBuilder and IConfigureOptions 31.3 Using a third-party dependency injection container 32 Building custom MVC and Razor Pages components 32.1 Creating a custom Razor Tag Helper Printing environment information with a custom Tag Helper Creating a custom Tag Helper to conditionally hide elements Creating a Tag Helper to convert Markdown to HTML 32.2 View components: Adding logic to partial views 32.3 Building a custom validation attribute 32.4 Replacing the validation framework with FluentValidation Comparing FluentValidation with DataAnnotations attributes Adding FluentValidation to your application 33 Calling remote APIs with IHttpClientFactory 33.1 Calling HTTP APIs: The problem with HttpClient 33.2 Creating HttpClients with IHttpClientFactory Using IHttpClientFactory to manage HttpClientHandler lifetime Configuring named clients at registration time Using typed clients to encapsulate HTTP calls 33.3 Handling transient HTTP errors with Polly 33.4 Creating a custom HttpMessageHandler 34 Building background tasks and ser vices 34.1 Running background tasks with IHostedService Running background tasks on a timer Using scoped services in background tasks 34.2 Creating headless worker services using IHost Creating a worker service from a template Running worker services in production 34.3 Coordinating background tasks using Quartz.NET Installing Quartz.NET in an ASP.NET Core application Configuring a job to run on a schedule with Quartz.NET Using clustering to add redundancy to your background tasks 35 Testing applications with xUnit 35.1 An introduction to testing in ASP.NET Core 35.2 Creating your first test project with xUnit 35.3 Running tests with dotnet test 35.4 Referencing your app from your test project 35.5 Adding Fact and Theory unit tests 35.6 Testing failure conditions 36 Testing ASP.NET Core applications 36.1 Unit testing custom middleware 36.2 Unit testing API controllers and minimal API endpoints 36.3 Integration testing: Testing your whole app in-memory Creating a TestServer using the Test Host package Testing your application with WebApplicationFactory Replacing dependencies in WebApplicationFactory Reducing duplication by creating a custom WebApplicationFactory 36.4 Isolating the database with an in-memory EF Core provider appendix A Preparing your development environment appendix B Useful references index front matter ce ASP.NET has a long history; Microsoft released the first version in 2002 as part of the original.NET Framework 1.0. Since then, it’s been through multiple iterations, each version bringing added features and extensibility. Each iteration, however, was built on the same underlying framework provided by System.Web.dll. This library is part of the.NET Framework, so it comes preinstalled in all versions of Windows. This brings mixed blessings. On one hand, the ASP.NET 4.X framework today is a reliable, battle-tested platform for building modern applications on Windows. On the other hand, it is limited by this reliance; changes to the underlying System.Web.dll are far-reaching and consequently slow to roll out, and it fundamentally excludes the many developers who are building and deploying to Linux or macOS. When I began looking into ASP.NET Core, I was one of those developers. A Windows user at heart, I was issued a Mac by my employer, so I was stuck working in a virtual machine all day. ASP.NET Core promised to change all that, allowing me to develop natively on both my Windows machine and my Mac. I was relatively late to the party in many respects, taking an active interest only just before the RC2 release of ASP.NET Core. By this point there had already been eight (!) beta releases, many of which contained significant breaking changes. By not diving in fully until RC2, I was spared the pain of dodgy tooling and changing APIs. What I saw at that point really impressed me. ASP.NET Core let developers use their existing knowledge of the.NET Framework, and of ASP.NET MVC applications in particular, while baking in current best practices such as dependency injection, strongly typed configuration, and logging. On top of that, you could build and deploy cross-platform. I was sold. This book came about largely due to my approach to learning about ASP.NET Core. Rather than simply reading documentation and blog posts, I decided to try something new and start writing about what I learned. Each week I would dedicate some time to exploring a new aspect of ASP.NET Core, and I’d write a blog post about it. When the possibility of writing a book came about, I jumped at the chance—another excuse to dive further into the framework! Since I started this book, a lot has changed, both with the book and ASP.NET Core. The first major release of the framework in June 2016 still had many rough edges, in particular around the tooling experience. With the release of.NET 7 in November 2022, ASP.NET Core has really come into its own, with the APIs and tooling reaching mature levels. Updates to the framework in.NET 6 and.NET 7 significantly simplified the getting-started experience for newcomers with the introduction of minimal hosting and minimal APIs, which provide a terser, simpler approach to writing APIs, much closer to the experience in other languages. You can get straight into building your app’s functionality without having to understand architecture first. For some experienced ASP.NET Core developers, these changes can feel regressive and unstructured, but if you’re one of them, I encourage you to give them a chance and to build your own structure and patterns. For brevity and clarity of the examples in this book, I often put the whole code for your app in one file, but don’t think that’s how you need to write your real applications. You’re free to create helper methods, classes, and any structure that helps keep your applications maintainable while taking advantage of the performance benefits of minimal APIs. This book covers everything you need to get started with ASP.NET Core, whether you’re new to web development or an existing ASP.NET developer. It focuses on the framework itself, so I don’t go into details about client-side frameworks such as Angular and React or technologies like Docker. I also don’t cover all the new features in.NET 7, such as Blazor and gRPC; instead, I provide links where you can find more information. In this edition, I have significantly expanded and rearranged many chapters compared with previous editions of the book; some chapters have been split into more manageable sizes. The early chapters feature a lot of new content focusing on minimal APIs and minimal hosting introduced in.NET 6. I find it a joy to work with ASP.NET Core apps compared with apps using the previous version of ASP.NET, and I hope that my passion comes through in this book! owledgments Although there is only one name on the cover of this book, a plethora of people contributed to both its writing and production. In this section I’d like to thank everyone who encouraged me, contributed, and put up with me for the past year. First, and most important, I’d like to thank my girlfriend, Becky. Your continual support and encouragement means the world to me and has kept me going through such a busy time. You’ve taken the brunt of my stress and pressure, and I’m eternally grateful. I love you always. I’d also like to thank my whole family for their support, in particular my parents, Jan and Bob, for putting up with my ranting; my sister, Amanda, for your always upbeat chats; and of course, Goose, for diligently ensuring that I take regular breaks for walks and tummy tickles. On a professional level, I’d like to thank Manning for giving me this opportunity. Brian Sawyer “discovered” me for the first version of this book and encouraged me to tackle the subsequent versions. Marina Michaels served as my development editor for the third time running and again proved to be alternately meticulous, critical, encouraging, and enthusiastic. The book is undoubtedly better thanks to your involvement. Thank you to my review editor, Adriana Sabo, and to all the reviewers: Alen Adanić, Ben McNamara, Bela Istók, Darrin Bishop, Dennis Liabenow, Al Pezewski, Emmanouil Chardalas, Foster Haines, Onofrei George, John Guthrie, Jean-François Morin, Pedro Seromenho, Joe Cuevas, José Antonio Martinez Perez, Joe Suchy, Luis Moux, Milan Šarenac, Milorad Imbra, Nik Rimington, Nitin Ainani, Oliver Korten, Raushan Jha, Richard Young, Rick Beerendonk, Ron Lease, Ruben Vandeginste, Sumit K. Singh, Towhidul Bashar, Daniel Vásquez, and Will Lopez. Your suggestions helped make this a better book. My thanks go to the technical editor for this book, Filip Wojcieszyn, who is a founder and maintainer of several popular open-source projects, frequent conference speaker, and a Microsoft MVP. Filip provided invaluable feedback, highlighting my incorrect assumptions and technical biases, and ensuring technical correctness in everything I wrote. I also wish to thank Tanya Wilke, who served as technical proofreader. Tanya verified that the code I wrote actually ran and made sense, working through the chapters with formidable efficiency. To everyone at Manning who helped get this book published and marketed, a heartfelt thanks. I’d also like to thank all the MEAP readers for their comments, which helped improve the book in numerous ways. I would have never been in a position to write this book if not for the excellent content produced by members of the.NET community and those I follow on social media. Finally, thanks to all those friends who encouraged and supported me, and showed interest generally. We may not have been able to meet up as much as we’d like, but I look forward to getting together for a drink as soon as it’s possible. t this book This book is about the ASP.NET Core framework, what it is, and how you can use it to build web applications. Although some of this content is already available online, it’s scattered around the internet in disparate documents and blog posts. This book guides you through building your first applications, introducing additional complexity as you cement previous concepts. I present each topic using relatively small examples rather than building on a single example application through the book. There are merits to both approaches, but I wanted to ensure that the focus remained on the specific topics being taught, without the mental overhead of navigating an increasingly large project. By the end of the book, you should have a solid understanding of how to build apps with ASP.NET Core, its strengths and weaknesses, and how to use its features to build apps securely. I don’t spend a lot of time on application architecture, but I make sure to point out best practices, especially where I cover architecture only superficially for the sake of brevity. should read this book This book is for C# developers who are interested in learning a cross-platform web framework. It doesn’t assume that you have any experience building web applications. You may be a mobile or desktop developer, for example, though experience with ASP.NET or another web framework is undoubtedly beneficial. I assume that in addition to a working knowledge of C# and.NET, you have some knowledge of common object-oriented practices and a basic understanding of relational databases in general. I assume passing familiarity with HTML and CSS and of JavaScript’s place as a client-side scripting language. You don’t need to know any JavaScript or CSS frameworks for this book, though ASP.NET Core works well with both if that is your forte. Web frameworks naturally touch on a wide range of topics, from the database and network to visual design and client-side scripting. I provide as much context as possible, and I include links to sites and books where you can learn more. this book is organized This book is divided into 5 parts, 36 chapters, and 2 appendices. Ideally, you will read the book cover to cover and then use it as a reference, but I realize that this approach won’t suit everyone. Although I use small sample apps to demonstrate a topic, some chapters build on the work of previous ones, so the content will make more sense when read sequentially. I strongly suggest reading the chapters in part 1 in sequence, as each chapter builds on topics introduced in the previous chapters and provides a basis for the rest of the book. Part 2 is also best read sequentially, though most of the chapters are independent if you wish to jump around. Part 3, again, is best read sequentially. You’ll get the best experience by reading the chapters in parts 4 and 5 sequentially, but many of the topics are independent, so you can read them out of order if you prefer. But I recommend only doing so after you’ve covered parts 1 to 3. Part 1 provides a general introduction to ASP.NET Core, focusing on building small JSON APIs by using the latest features introduced in.NET 7. After we cover the basics, we look at building minimal API applications that provide the simplest programming model for ASP.NET Core web applications. Chapter 1 introduces ASP.NET Core and its place in the web development landscape. It describes the type of applications you can build, some of the reasons to choose ASP.NET Core, and the basics of web requests in an ASP.NET Core application. Chapter 2 looks at why you should consider using any web framework, why ASP.NET Core was created, and the different application paradigms you can use with ASP.NET Core. Finally, it looks at the situations when you should and shouldn’t choose ASP.NET Core. Chapter 3 walks through all the components of a basic ASP.NET Core minimal API application, discussing their role and how they combine to generate a response to a web request. Chapter 4 describes the middleware pipeline, the main application pipeline in ASP.NET Core, which defines how incoming requests are processed and how a response should be generated. Chapter 5 shows how to use minimal API endpoints to create a JavaScript Object Notation (JSON) HTTP API that can be called by client-side apps, server-side apps, or mobile devices. Chapter 6 describes the ASP.NET Core routing system. Routing is the process of mapping incoming request URLs to a specific handler method, which executes to generate a response. Chapter 7 looks at model binding in minimal APIs, the process of mapping form data and URL parameters passed in a request to concrete C# objects. Part 2 covers important topics for building fully-featured web applications after you understand the basics: Chapter 8 introduces the concept of dependency injection (DI) and describes the DI container built into ASP.NET Core. Chapter 9 builds on chapter 8 by describing how to register your own services with the DI container, the patterns you can use, and how to understand the lifetime of services the DI container creates. Chapter 10 discusses how to read settings and secrets in ASP.NET Core, and how to map them to strongly typed objects. Chapter 11 describes how to document your APIs using the OpenAPI standard and how this helps with testing scenarios and for automatically generating clients to call your APIs. Chapter 12 introduces Entity Framework Core (EF Core) for saving data in a relational database. Part 3 moves away from minimal APIs and looks at how to build server-rendered page-based HTML applications using Razor Pages and the Model-View-Controller (MVC) architecture: Chapter 13 shows how to use Razor Pages to build page-based web sites. Razor Pages are the recommended way to build server-rendered applications in ASP.NET Core and are designed for page-based applications. Chapter 14 describes the Razor Pages routing system and how it differs from minimal APIs. Chapter 15 looks at page handlers in Razor Pages, which are responsible for choosing how to respond to a request and selecting what response to generate. Chapter 16 looks at model binding in Razor Pages, how it differs from minimal APIs, and the importance of validating your models. Chapter 17 shows how to generate HTML web pages using the Razor template language. Chapter 18 builds on chapter 17 by introducing Tag Helpers, which can greatly reduce the amount of code required to build forms and web pages. Chapter 19 introduces MVC controllers as an alternative approach to building both server-rendered HTML applications and API applications. Chapter 20 describes how to use MVC controllers to build APIs that can be called by client-side apps as an alternative to minimal APIs. Chapter 21 introduces the MVC and Razor Pages filter pipeline, shows how it works, and describes some of the filters built into the framework. Chapter 22 builds on chapter 21 by showing how to create custom filters to reduce some of the duplication in your MVC and Razor Pages applications. The chapters that make up part 4 cover important cross-cutting aspects of ASP.NET Core development: Chapter 23 describes how to add user profiles and authentication to your application by using ASP.NET Core Identity. Chapter 24 builds on the previous chapter by introducing authorization for users so you can restrict which pages a signed-in user can access. Chapter 25 discusses authentication and authorization for API applications, how this differs from authentication in HTML applications, and how to get started with authentication in ASP.NET Core APIs. Chapter 26 shows how to configure logging in your application and how to write log messages to multiple locations. Chapter 27 looks at how to publish your app and configure it for a production environment. Chapter 28 discusses the reason for adding HTTPS to your application, how to use HTTPS when developing locally and in production, and how to force HTTPS for your whole application. Chapter 29 explores some other security considerations you should make when developing your application and how to stay safe with ASP.NET Core. Part 5 looks at various topics that help you take your ASP.NET Core applications further, including nonweb applications, custom configuration and components, and testing: Chapter 30 discusses an alternative bootstrapping approach for ASP.NET Core apps, using the generic host and a Startup class. Chapter 31 describes how to build and use a variety of custom components, such as custom middleware, and how to handle complex configuration requirements. Chapter 32 expands on chapter 31, showing how to build custom Razor Page components such as custom Tag Helpers and custom validation attributes. Chapter 33 discusses the IHttpClientFactory service and how to use it to create HttpClient instances for calling remote APIs. Chapter 34 explores the generic IHost abstraction, which you can use to create Windows Services and Linux daemons. You’ll also learn to run tasks in the background of your applications. Chapter 35 shows how to test an ASP.NET Core application with the xUnit testing framework. Chapter 36 follows on from chapter 35, showing how to test ASP.NET Core applications specifically. It covers both unit tests and integration tests using the Test Host. The two appendices provide supplementary information: Appendix A describes how to configure your development environment, whether you’re in Windows, Linux, or macOS. Appendix B contains links that I’ve found useful in learning about ASP.NET Core. t the code Source code is provided for all chapters except chapters 1, 2, 21, and 27, which don’t have any code. You can view the source code for each chapter in my GitHub repository at https://github.com/andrewlock/asp-dot-net-core-in-action-3e. A zip file containing all the source code is also available on the publisher’s website at https://www.manning.com/books/asp-net- core-in-action-third-edition. You can get executable snippets of code from the liveBook (online) version of this book at https://livebook.manning.com/book/asp-net-core-in-action-third- edition. All the code examples in this book use.NET 7 and were built using both Visual Studio and Visual Studio Code. To build and run the examples, you need to install the.NET software development kit (SDK), as described in appendix A. This book contains many examples of source code, both in numbered listings and inline with normal text. In both cases, source code is formatted in a fixed-width font like this to separate it from ordinary text. Sometimes code is also in bold to highlight changes from previous steps in the chapter, such as when a new feature adds to an existing line of code. In many cases, the original source code has been reformatted; we’ve added line breaks and reworked indentation to accommodate the available page space in the book. In rare cases, even this was not enough, and some listings include line- continuation markers (➥). Additionally, comments in the source code have been removed from the listings when the code is described in the text. Code annotations accompany many of the listings, highlighting important concepts. ook discussion forum Purchase of ASP.NET Core in Action, Third Edition, includes free access to liveBook, Manning’s online reading platform. Using liveBook’s exclusive discussion features, you can attach comments to the book globally or to specific sections or paragraphs. It’s a snap to make notes for yourself, ask and answer technical questions, and receive help from the author and other users. To access the forum, go to https://livebook.manning.com/book/asp-net-core-in-action-third- edition/discussion. You can also learn more about Manning’s forums and the rules of conduct at https://livebook.manning.com/discussion. Manning’s commitment to our readers is to provide a venue where a meaningful dialogue between individual readers and between readers and the author can take place. It is not a commitment to any specific amount of participation on the part of the author, whose contribution to the forum remains voluntary (and unpaid). We suggest that you try asking the author some challenging questions lest his interest stray! The forum and the archives of previous discussions will be accessible on the publisher’s website as long as the book is in print. t the author Andrew Lock is a.NET developer and Microsoft MVP. He graduated with an engineering degree from Cambridge University, specializing in software engineering, and went on to obtain a PhD in digital image processing. He has been developing professionally with.NET since 2010, using a wide range of technologies, including WinForms, ASP.NET WebForms, ASP.NET MVC, ASP.NET Webpages, and most recently ASP.NET Core. Andrew has put many ASP.NET Core applications into production since version 1 was released in 2016. He has an active blog at https://andrewlock.net dedicated to ASP.NET Core. This blog has frequently been featured in the community spotlight by the ASP.NET team at Microsoft, on the.NET blog, and in the weekly community standups. t the cover illustration The caption for the illustration on the cover of ASP.NET Core in Action, Third Edition, is “The Captain Pasha. Kapudan pasha, admiral of the Turkish navy,” taken from a collection published in 1802 by William Miller. In those days, it was easy to identify where people lived and what their trade or station in life was by their dress alone. Manning celebrates the inventiveness and initiative of the computer business with book covers based on the rich diversity of regional culture centuries ago, brought back to life by pictures from collections such as this one. 1 Getting started with ASP.NET Core This chapter covers What is ASP.NET Core? Things you can build with ASP.NET Core How ASP.NET Core works Choosing to learn and develop with a new framework is a big investment, so it’s important to establish early on whether it’s right for you. In this chapter, I provide some background on ASP.NET Core: what it is, how it works, and why you should consider it for building your web applications. By the end of this chapter, you should have a good overview of the benefits of ASP.NET Core, the role of.NET 7, and the basic mechanics of how ASP.NET Core works. So without further ado, let’s dive in! hat is ASP.NET Core? ASP.NET Core is a cross-platform, open-source application framework that you can use to build dynamic web applications quickly. You can use ASP.NET Core to build server-rendered web applications, backend server applications, HTTP APIs that can be consumed by mobile applications, and much more. ASP.NET Core runs on.NET 7, which is the latest version of.NET Core—a high-performance, cross-platform, open-source runtime. ASP.NET Core provides structure, helper functions, and a framework for building applications, which saves you from having to write a lot of this code yourself. Then the ASP.NET Core framework code calls in to your handlers, which in turn call methods in your application’s business logic, as shown in figure 1.1. This business logic is the core of your application. You can interact with other services here, such as databases or remote APIs, but your business logic typically doesn’t depend directly on ASP.NET Core. Figure 1.1 A typical ASP.NET Core application consists of several layers. The ASP.NET Core framework code handles requests from a client, dealing with the complex networking code. Then the framework calls in to handlers (Razor Pages and Web API controllers, for example) that you write using primitives provided by the framework. Finally, these handlers call in to your application’s domain logic—typically, C# classes and objects without any dependencies that are specific to ASP.NET Core. hat types of applications can you build? ASP.NET Core provides a generalized web framework that you can use to build a wide variety of applications. ASP.NET Core includes APIs that support many paradigms: Minimal APIs—Simple HTTP APIs that can be consumed by mobile applications or browser-based single-page applications. Web APIs—An alternative approach to building HTTP APIs that adds more structure and features than minimal APIs. gRPC APIs—Used to build efficient binary APIs for server-to- server communication using the gRPC protocol. Razor Pages—Used to build page-based server-rendered applications. MVC controllers—Similar to Razor Pages. Model-View- Controller (MVC) controller applications are for server-based applications but without the page-based paradigm. Blazor WebAssembly—A browser-based single-page application framework that uses the WebAssembly standard, similar to JavaScript frameworks such as Angular, React, and Vue. Blazor Server—Used to build stateful applications, rendered on the server, that send UI events and page updates over WebSockets to provide the feel of a client-side single-page application, but with the ease of development of a server- rendered application. All these paradigms are based on the same building blocks of ASP.NET Core, such as the configuration and logging libraries, and then place extra functionality on top. The best paradigm for your application depends on multiple factors, including your API requirements, the details of existing applications you need to interact with, the details of your customers’ browsers and operating environment, and scalability and uptime requirements. You don’t need to choose only one of these paradigms; ASP.NET Core can combine multiple paradigms within a single application. hoosing ASP.NET Core I hope that now you have a general grasp of what ASP.NET Core is and the type of applications you can build with it. But one question remains: should you use it? Microsoft recommends that all new.NET web development use ASP.NET Core, but switching to or learning a new web stack is a big ask for any developer or company. If you’re new to.NET development and are considering ASP.NET Core, welcome! Microsoft is pushing ASP.NET Core as an attractive option for web development beginners, but taking.NET cross-platform means that it’s competing with many other frameworks on their own turf. ASP.NET Core has many selling points compared with other cross-platform web frameworks: It’s a modern, high-performance, open-source web framework. It uses familiar design patterns and paradigms. C# is a great language (but you can use VB.NET or F# if you prefer). You can build and run on any platform. ASP.NET Core is a reimagining of the ASP.NET framework, built with modern software design principles on top of the new.NET platform. Although it’s new in one sense,.NET (previously called.NET Core) has had widespread production use since 2016 and has drawn significantly from the mature, stable, and reliable.NET Framework, which has been used for more than two decades. You can rest easy knowing that by choosing ASP.NET Core and.NET 7, you’re getting a dependable platform as well as a full-featured web framework. One major selling point of ASP.NET Core and.NET 7 is the ability to develop and run on any platform. Whether you’re using a Mac, Windows, or Linux computer, you can run the same ASP.NET Core apps and develop across multiple environments. A wide range of distributions are supported for Linux users: RHEL, Ubuntu, Debian, CentOS, Fedora, and openSUSE, to name a few. ASP.NET Core even runs on the tiny Alpine distribution, for truly compact deployments to containers, so you can be confident that your operating system of choice will be a viable option. If you’re already a.NET developer, the choice of whether to invest in ASP.NET Core for new applications was largely a question of timing. Early versions of.NET Core lacked some features that made it hard to adopt, but that problem no longer exists in the latest versions of.NET. Now Microsoft explicitly advises that all new.NET applications should use.NET 7 (or newer). Microsoft has pledged to provide bug and security fixes for the older ASP.NET framework, but it won’t provide any more feature updates..NET Framework isn’t being removed, so your old applications will continue to work, but you shouldn’t use it for new development. The main benefits of ASP.NET Core over the previous ASP.NET framework are Cross-platform development and deployment Focus on performance as a feature A simplified hosting model Regular releases with a shorter release cycle Open-source Modular features More application paradigm options The option to package.NET with an app when publishing for standalone deployments As an existing.NET developer who’s moving to ASP.NET Core, your ability to build and deploy cross-platform opens the door to a whole new avenue of applications, such as taking advantage of cheaper Linux virtual machine hosting in the cloud, using Docker containers for repeatable continuous integration, or writing.NET code on your Mac without needing to run a Windows virtual machine. ASP.NET Core, in combination with.NET 7, makes all this possible. That’s not to say that your experience deploying ASP.NET applications to Windows and Internet Information Services (IIS) is wasted. On the contrary, ASP.NET Core uses many of the same concepts as the previous ASP.NET framework, and you can still run your ASP.NET Core applications in IIS, so moving to ASP.NET Core doesn’t mean starting from scratch. ow does ASP.NET Core work? I’ve covered the basics of what ASP.NET Core is, what you can use it for, and why you should consider using it. In this section, you’ll see how an application built with ASP.NET Core works, from a user request for a URL to the display of a page in the browser. To get there, first you’ll see how an HTTP request works for any web server; then you’ll see how ASP.NET Core extends the process to create dynamic web pages. How does an HTTP web request work? As you know now, ASP.NET Core is a framework for building web applications that serve data from a server. One of the most common scenarios for web developers is building a web app that you can view in a web browser. Figure 1.2 shows the high- level process you can expect from any web server. Figure 1.2 Requesting a web page. The user starts by requesting a web page, which causes an HTTP request to be sent to the server. The server interprets the request, generates the necessary HTML, and sends it back in an HTTP response. Then the browser can display the web page. The process begins when a user navigates to a website or types a URL in their browser. The URL or web address consists of a hostname and a path to some resource on the web app. Navigating to the address in the browser sends a request from the user’s computer to the server on which the web app is hosted, using the HTTP protocol. DEFINITION The hostname of a website uniquely identifies its location on the internet by mapping via the Domain Name Service (DNS) to an IP address. Examples include microsoft.com, www.google.co.uk, and facebook.com. A brief primer on HTTP Hypertext Transfer Protocol (HTTP) is the application-level protocol that powers the web. It’s a stateless request-response protocol whereby a client machine sends a request to a server, which sends a response in turn. Every HTTP request consists of a verb indicating the type of the request and a path indicating the resource to interact with. A request typically also includes headers, which are key-value pairs, and in some cases a body, such as the contents of a form, when sending data to the server. An HTTP response contains a status code, indicating whether the request was successful, and optionally headers and a body. For a more detailed look at the HTTP protocol itself, as well as more examples, see section 1.3 (“A quick introduction to HTTP”) of Go Web Programming, by Sau Sheong Chang (Manning, 2016), at http://mng.bz/x4mB. You can also read the raw RFC specification at https://www.rfc-editor.org/rfc/rfc9110.txt if dense text is your thing! The request passes through the internet, potentially to the other side of the world, until it finally makes its way to the server associated with the given hostname, on which the web app is running. The request is potentially received and rebroadcast at multiple routers along the way, but only when it reaches the server associated with the hostname is the request processed. When the server receives the request, it processes that request and generates an HTTP response. Depending on the request, this response could be a web page, an image, a JavaScript file, a simple acknowledgment, or practically any other file. For this example, I’ll assume that the user has reached the home page of a web app, so the server responds with some HTML. The HTML is added to the HTTP response, which is sent back across the internet to the browser that made the request. As soon as the user’s browser begins receiving the HTTP response, it can start displaying content on the screen, but the HTML page may also reference other pages and links on the server. To display the complete web page instead of a static, colorless, raw HTML file, the browser must repeat the request process, fetching every referenced file. HTML, images, Cascading Style Sheets (CSS) for styling, and JavaScript files for extra behavior are all fetched using exactly the same HTTP request process. Pretty much all interactions that take place on the internet are a facade over this basic process. A basic web page may require only a few simple requests to render fully, whereas a large modern web page may take hundreds. At this writing, the Amazon.com home page (https://www.amazon.com) makes 410 requests, including requests for 4 CSS files, 12 JavaScript files, and 299 image files! Now that you have a feel for the process, let’s see how ASP.NET Core dynamically generates the response on the server. How does ASP.NET Core process a request? When you build a web application with ASP.NET Core, browsers will still be using the same HTTP protocol as before to communicate with your application. ASP.NET Core itself encompasses everything that takes place on the server to handle a request, including verifying that the request is valid, handling login details, and generating HTML. As with the generic web page example, the request process starts when a user’s browser sends an HTTP request to the server, as shown in figure 1.3. Figure 1.3 How an ASP.NET Core application processes a request. A request is received by the ASP.NET Core application, which runs a self-hosted web server. The web server processes the request and passes it to the body of the application, which generates a response and returns it to the web server. The web server sends this response to the browser. The request is received from the network by your ASP.NET Core application. Every ASP.NET Core application has a built-in web server—Kestrel, by default—that is responsible for receiving raw requests and constructing an internal representation of the data, an HttpContext object, which the rest of the application can use. Your application can use the details stored in HttpContext to generate an appropriate response to the request, which may be to generate some HTML, to return an “access denied” message, or to send an email, all depending on your application’s requirements. When the application finishes processing the request, it returns the response to the web server. The ASP.NET Core web server converts the representation to a raw HTTP response and sends it to the network, which forwards it to the user’s browser. To the user, this process appears to be the same as for the generic HTTP request shown in figure 1.2: the user sent an HTTP request and received an HTTP response. All the differences are server-side, within your application. You’ve seen how requests and responses find their way to and from an ASP.NET Core application, but I haven’t yet touched on how the response is generated. Throughout this book, we’ll look at the components that make up a typical ASP.NET Core application and how they fit together. A lot goes into generating a response in ASP.NET Core, typically within a fraction of a second, but over the course of the book we’ll step through an application slowly, covering each of the components in detail. hat you’ll learn in this book This book takes you on an in-depth tour of the ASP.NET Core framework. To benefit from the book, you should be familiar with C# or a similar object-oriented language. Basic familiarity with web concepts such as HTML and JavaScript will also be beneficial. You’ll learn the following: How to build HTTP API applications using minimal APIs How to create page-based applications with Razor Pages Key ASP.NET Core concepts such as model-binding, validation, and routing How to generate HTML for web pages by using Razor syntax and Tag Helpers How to use features such as dependency injection, configuration, and logging as your applications grow more complex How to protect your application by using security best practices Throughout the book we’ll use a variety of examples to learn and explore concepts. The examples are generally small and self-contained so that we can focus on a single feature at a time. I’ll be using Visual Studio for most of the examples in this book, but you’ll be able to follow along using your favorite editor or integrated development environment (IDE). Appendix A includes details on setting up your editor or IDE and installing the.NET 7 software development kit (SDK). Even though the examples in this book show Windows tools, everything you see can be achieved equally well on the Linux or Mac platform. TIP You can install.NET 7 from https://dotnet.microsoft.com/download. Appendix A contains further details on configuring your development environment to work with ASP.NET Core and.NET 7. In chapter 2, we’ll look in greater depth at the types of applications you can create with ASP.NET Core. We’ll also explore its advantages over the older ASP.NET and.NET Framework platforms. mary ASP.NET Core is a cross-platform, open-source, high- performance web framework. ASP.NET Core runs on.NET, previously called.NET Core. You can use Razor Pages or MVC controllers to build server- rendered, page-based web applications. You can use minimal APIs or web APIs to build RESTful or HTTP APIs. You can use gRPC to build highly efficient server-to-server RPC applications. You can use Blazor WebAssembly to build client-side applications that run in the browser and Blazor Server to build stateful, server-rendered applications that send UI updates via a WebSocket connection. Microsoft recommends ASP.NET Core and.NET 7 or later for all new web development over the legacy ASP.NET and.NET Framework platforms. Fetching a web page involves sending an HTTP request and receiving an HTTP response. ASP.NET Core allows you to build responses to a given request dynamically. An ASP.NET Core application contains a web server, which serves as the entry point for a request. Part 1 Getting started with minimal APIs Web applications are everywhere these days, from social media web apps and news sites to the apps on your phone. Behind the scenes, there’s almost always a server running a web application or an HTTP API. Web applications are expected to be infinitely scalable, deployed to the cloud, and highly performant. Getting started can be overwhelming at the best of times, and doing so with such high expectations can be even more of a challenge. The good news for you as a reader is that ASP.NET Core was designed to meet those requirements. Whether you need a simple website, a complex e-commerce web app, or a distributed web of microservices, you can use your knowledge of ASP.NET Core to build lean web apps that fit your needs. ASP.NET Core lets you build and run web apps in Windows, Linux, or macOS. It’s highly modular, so you use only the components you need, keeping your app as compact and performant as possible. In part 1 you’ll go from a standing start all the way to building your first API applications. Chapter 2 gives you a high-level overview of ASP.NET Core, which you’ll find especially useful if you’re new to web development in general. You’ll get your first glimpse of a full ASP.NET Core application in chapter 3; we’ll look at each component of the app in turn and see how they work together to generate a response. Chapter 4 looks in detail at the middleware pipeline, which defines how incoming web requests are processed and how a response is generated. We’ll look at several standard pieces of middleware and see how they can be combined to create your application’s pipeline. Chapters 5 through 7 focus on building ASP.NET Core apps with minimal API endpoints, which are the new simplified approach to building JSON APIs in ASP.NET Core apps. In chapter 5 you’ll learn how to create endpoints that generate JSON, how to use filters to extract common behavior, and how to use route groups to organize your APIs. In chapter 6 you’ll learn about routing, the process of mapping URLs to endpoints. And in chapter 7 you’ll learn about model binding and validation. There’s a lot of content in part 1, but by the end you’ll be well on your way to building simple APIs with ASP.NET Core. Inevitably, I’ll gloss over some of the more complex configuration aspects of the framework, but you should get a good understanding of minimal APIs and how you can use them to build simple APIs. In later parts of this book, you’ll learn how to configure your application and add extra features, such as user profiles and database interaction. We’ll also look at how to build other types of applications, such as server-rendered web apps with Razor Pages. 2 Understanding ASP.NET Core This chapter covers Why ASP.NET Core was created The many application paradigms of ASP.NET Core Approaches to migrating an existing application to ASP.NET Core In this chapter, I provide some background on ASP.NET Core: why web frameworks are useful, why ASP.NET Core was created, and how to choose when to use ASP.NET Core. If you’re new to.NET development, this chapter will help you understand the.NET landscape. If you’re already a.NET developer, I provide guidance on whether now is the right time to consider moving your focus to.NET Core and.NET 7, as well as on the advantages ASP.NET Core can offer over previous versions of ASP.NET. sing a web framework If you’re new to web development, it can be daunting to move into an area with so many buzzwords and a plethora of ever- changing products. You may be wondering whether all those products are necessary. How hard can it be to return a file from a server? Well, it’s perfectly possible to build a static web application without the use of a web framework, but its capabilities will be limited. As soon as you want to provide any kind of security or dynamism, you’ll likely run into difficulties, and the original simplicity that enticed you will fade before your eyes. Just as desktop or mobile development frameworks can help you build native applications, ASP.NET Core makes writing web applications faster, easier, and more secure than trying to build everything from scratch. It contains libraries for common things like Creating dynamically changing web pages Letting users log in to your web app Letting users use their Facebook accounts to log in to your web app Providing a common structure for building maintainable applications Reading configuration files Serving image files Logging requests made to your web app The key to any modern web application is the ability to generate dynamic web pages. A dynamic web page may display different data depending on the current logged-in user, or it could display content submitted by users. Without a dynamic framework, it wouldn’t be possible to log in to websites or to display any sort of personalized data on a page. In short, websites like Amazon, eBay, and Stack Overflow (shown in figure 2.1) wouldn’t be possible. Web frameworks for creating dynamic web pages are almost as old as the web itself, and Microsoft has created several over the years, so why create a new one? Figure 2.1 The Stack Overflow website (https://stackoverflow.com) is built with ASP.NET and has almost entirely dynamic content. hy ASP.NET Core was created Microsoft’s development of ASP.NET Core was motivated by the desire to create a web framework with five main goals: To be run and developed cross-platform To have a modular architecture for easier maintenance To be developed completely as open-source software To adhere to web standards To be applicable to current trends in web development, such as client-side applications and deployment to cloud environments To achieve all these goals, Microsoft needed a platform that could provide underlying libraries for creating basic objects such as lists and dictionaries, and for performing tasks such as simple file operations. Up to this point, ASP.NET development had always been focused—and dependent—on the Windows- only.NET Framework. For ASP.NET Core, Microsoft created a lightweight platform that runs on Windows, Linux, and macOS called.NET Core (subsequently.NET), as shown in figure 2.2. Figure 2.2 The relationships among ASP.NET Core, ASP.NET,.NET Core/.NET 5+, and.NET Framework. ASP.NET Core runs on.NET Core and.NET 5+, so it can run cross-platform. Conversely, ASP.NET runs on.NET Framework only, so it’s tied to the Windows OS. DEFINITION.NET 5 was the next version of.NET Core after 3.1, followed by.NET 6 and.NET 7. It represents a unification of.NET Core and other.NET platforms in a single runtime and framework. It was considered to be the future of.NET, which is why Microsoft chose to drop the “Core” from its name. For consistency with Microsoft’s language, I use the term.NET 5+ to refer to.NET 5,.NET 6, and.NET 7, and the term.NET Core to refer to previous versions..NET Core (and its successor,.NET 5+) employs many of the same APIs as.NET Framework but is more modular. It implements a different set of features from those in.NET Framework, with the goal of providing a simpler programming model and modern APIs. It’s a separate platform rather than a fork of.NET Framework, though it uses similar code for many of its APIs. NOTE If you’d like to learn more about the.NET ecosystem, you can read two posts on my blog: “Understanding the.NET ecosystem: The evolution of.NET into.NET 7” (http://mng.bz/Ao0W) and “Understanding the.NET ecosystem: The introduction of.NET Standard” (http://mng.bz/ZqPZ). The benefits and limitations of ASP.NET ASP.NET Core is the latest evolution of Microsoft’s popular ASP.NET web framework, released in June 2016. Previous versions of ASP.NET had many incremental updates, focusing on high developer productivity and prioritizing backward compatibility. ASP.NET Core bucks that trend by making significant architectural changes that rethink the way the web framework is designed and built. ASP.NET Core owes a lot to its ASP.NET heritage, and many features have been carried forward from before, but ASP.NET Core is a new framework. The whole technology stack has been rewritten, including both the web framework and the underlying platform. At the heart of the changes is the philosophy that ASP.NET should be able to hold its head high when measured against other modern frameworks, but existing.NET developers should continue to have a sense of familiarity. To understand why Microsoft decided to build a new framework, it’s important to understand the benefits and limitations of the legacy ASP.NET web framework. The first version of ASP.NET was released in 2002 as part of.NET Framework 1.0. The ASP.NET Web Forms paradigm that it introduced differed significantly from the conventional scripting environments of classic ASP and PHP. ASP.NET Web Forms allowed developers to create web applications rapidly by using a graphical designer and a simple event model that mirrored desktop application-building techniques. The ASP.NET framework allowed developers to create new applications quickly, but over time the web development ecosystem changed. It became apparent that ASP.NET Web Forms suffered from many problems, especially in building larger applications. In particular, a lack of testability, a complex stateful model, and limited influence on the generated HTML (making client-side development difficult) led developers to evaluate other options. In response, Microsoft released the first version of ASP.NET MVC in 2009, based on the Model-View-Controller (MVC) pattern, a common web pattern used in frameworks such as Ruby on Rails, Django, and Java Spring. This framework allowed developers to separate UI elements from application logic, made testing easier, and provided tighter control of the HTML-generation process. ASP.NET MVC has been through four more iterations since its first release, but all these iterations were built on the same underlying framework provided by the System.Web.dll file. This library is part of.NET Framework, so it comes preinstalled with all versions of Windows. It contains all the core code that ASP.NET uses when you build a web application. This dependency brings both advantages and disadvantages. On one hand, the ASP.NET framework is a reliable, battle-tested platform that’s fine for building web applications in Windows. It provides a wide range of features that have been in production for many years, and it’s well known by virtually all Windows web developers. On the other hand, this reliance is limiting. Changes to the underlying System.Web.dll file are far-reaching and, consequently, slow to roll out, which limits the extent to which ASP.NET is free to evolve and results in release cycles happening only every few years. There’s also an explicit coupling with the Windows web host, Internet Information Services (IIS), which precludes its use on non-Windows platforms. More recently, Microsoft declared.NET Framework to be “done.” It won’t be removed or replaced, but it also won’t receive any new features. Consequently, ASP.NET based on System.Web.dll won’t receive new features or updates either. In recent years, many web developers have started looking at cross-platform web frameworks that can run on Windows as well as Linux and macOS. Microsoft felt the time had come to create a framework that was no longer tied to its Windows legacy; thus, ASP.NET Core was born. With.NET 7, it’s possible to build console applications that run cross-platform. Microsoft created ASP.NET Core to be an additional layer on top of console applications so that converting to a web application involves adding and composing libraries, as shown in figure 2.3. Figure 2.3 ASP.NET Core application model. The.NET 7 platform provides a base console application model for running command-line apps. Adding a web server library converts this model to an ASP.NET Core web app. You can add other features, such as configuration and logging, using various libraries. When you add an ASP.NET Core web server to your.NET 7 app, your console application can run as a web application. ASP.NET Core contains a huge number of APIs, but you’ll rarely need all the features available to you. Some of the features are built in and will appear in virtually every application you create, such as the ones for reading configuration files or performing logging. Other features are provided by separate libraries and built on top of these base capabilities to provide application- specific functionality, such as third-party logins via Facebook or Google. Most of the libraries and APIs you’ll use in ASP.NET Core are available on GitHub, in the Microsoft.NET organization repositories at https://github.com/dotnet/aspnetcore. You can find the core APIs there, including the authentication and logging APIs, as well as many peripheral libraries, such as the third-party authentication libraries. All ASP.NET Core applications follow a similar design for basic configuration, but in general the framework is flexible, leaving you free to create your own code conventions. These common APIs, the extension libraries that build on them, and the design conventions they promote are covered by the somewhat- nebulous term ASP.NET Core. nderstanding the many paradigms of ASP.NET Core In chapter 1 you learned that ASP.NET Core provides a generalized web framework that can be used to build a wide variety of applications. As you may recall from section 1.2, the main paradigms are Minimal APIs—Simple HTTP APIs that can be consumed by mobile applications or browser-based single-page applications (SPAs) Web APIs—An alternative approach for building HTTP APIs that adds more structure and features than minimal APIs gRPC APIs—Used to build efficient binary APIs for server-to- server communication using the gRPC protocol Razor Pages—Used to build page-based server-rendered applications MVC controllers—Similar to Razor Pages; used for server- based applications but without the page-based paradigm Blazor WebAssembly—A browser-based SPA framework using the WebAssembly standard, similar to JavaScript frameworks such as Angular, React, and Vue Blazor Server—Used to build stateful applications, rendered on the server, that send UI events and page updates over WebSockets to provide the feel of a client-side SPA but with the ease of development of a server-rendered application All these paradigms use the core functionality of ASP.NET Core and layer the additional functionality on top. Each paradigm is suited to a different style of web application or API, so some may fit better than others, depending on what sort of application you’re building. Traditional page-based, server-side-rendered web applications are the bread and butter of ASP.NET development, both in the previous version of ASP.NET and now in ASP.NET Core. The Razor Pages and MVC controller paradigms provide two slightly different styles for building these types of applications but have many of the same concepts, as you’ll see in part 2. These paradigms can be useful for building rich, dynamic websites, whether they’re e-commerce sites, content management systems (CMSes), or large n-tier applications. Both the open- source CMS Orchard Core1 (figure 2.4) and cloudscribe2 CMS project, for example, are built with ASP.NET Core. Figure 2.4 The California School Information Services website (https://csis.fcmat.org) is built with Orchard Core and ASP.NET Core. In addition to server-rendered applications, ASP.NET core is ideally suited to building a REST or HTTP API server. Whether you’re building a mobile app, a JavaScript SPA using Angular, React, Vue, or some other client-side framework, it’s easy to create an ASP.NET Core application to act as the server-side API by using both the minimal API and web API paradigms built into ASP.NET Core. You’ll learn about minimal APIs in part 1 and about web APIs in chapter 20. DEFINITION REST stands for representational state transfer. RESTful applications typically use lightweight and stateless HTTP calls to read, post (create/ update), and delete data. ASP.NET Core isn’t restricted to creating RESTful services. It’s easy to create a web service or remote procedure call (RPC)- style service for your application, using gRPC for example, as shown in figure 2.5. In the simplest case, your application might expose only a single endpoint! ASP.NET Core is perfectly designed for building simple services, thanks to its cross- platform support and lightweight design. DEFINITION gRPC is a modern open-source, high-performance RPC framework. You can read more at https://grpc.io. Figure 2.5 ASP.NET Core can act as the server-side application for a variety of clients: it can serve HTML pages for traditional web applications, act as a REST API for client-side SPA applications, or act as an ad hoc RPC service for client applications. As well as server-rendered web apps, APIs, and gRPC endpoints, ASP.NET Core includes the Blazor framework, which can be used to build two very different styles of application. Blazor WebAssembly (WASM) apps run directly in your browser, in the same way as traditional JavaScript SPA frameworks such as Angular and React. Your.NET code is compiled to WebAssembly (https://webassembly.org) or executes on a.NET runtime compiled for WASM, and the browser downloads and runs it as it would a JavaScript app. This way you can build highly interactive client-side applications while using C# and all the.NET APIs and libraries you already know. By contrast, Blazor Server applications run on the server. Each mouse click or keyboard event is sent to the server via WebSockets. Then the server calculates the changes that should be made to the UI and sends the required changes back to the client, which updates the page in the browser. The result is a “stateful” application that runs server-side but can be used to build highly interactive SPAs. The main downside of Blazor Server is that it requires a constant internet connection. NOTE In this book I focus on building traditional page-based, server-side- rendered web applications and RESTful web APIs. I also show how to create background worker services in chapter 34. For more information on Blazor, I recommend Blazor in Action, by Chris Sainty (Manning, 2022). With the ability to call on all these paradigms, you can use ASP.NET Core to build a wide variety of applications, but it’s still worth considering whether ASP.NET Core is right for your specific application. That decision will likely be affected by both your experience with.NET and the application you want to build. hen to choose ASP.NET Core In this section I’ll describe some of the points to consider when deciding whether to use ASP.NET Core and.NET 7 instead of legacy.NET Framework ASP.NET. In most cases the decision will be to use ASP.NET Core, but you should consider some important caveats. When choosing a platform, you should consider multiple factors, not all of which are technical. One such factor is the level of support you can expect to receive from its creators. For some organizations, limited support can be one of the main obstacles to adopting open-source software. Luckily, Microsoft has pledged to provide full support for Long Term Support (LTS) versions of.NET and ASP.NET Core for at least three years from the time of their release. And as all development takes place in the open, sometimes you can get answers to your questions from the general community as well as from Microsoft directly. NOTE You can view Microsoft’s official support policy at http://mng.bz/RxXP. When deciding whether to use ASP.NET Core, you have two primary dimensions to consider: whether you’re already a.NET developer and whether you’re creating a new application or looking to convert an existing one. If you’re new to.NET development If you’re new to.NET development, you’re joining at a great time! Many of the growing pains associated with a new framework have been worked out, and the result is a stable, high-performance, cross-platform application framework. The primary language of.NET development, and of ASP.NET Core in particular, is C#. This language has a huge following, for good reason! As an object-oriented C-based language, it provides a sense of familiarity to those who are used to C, Java, and many other languages. In addition, it has many powerful features, such as Language Integrated Query (LINQ), closures, and asynchronous programming constructs. The C# language is also designed in the open on GitHub, as is Microsoft’s C# compiler, code-named Roslyn (https://github.com/dotnet/roslyn). NOTE I use C# throughout this book and will highlight some of the newer features it provides, but I won’t be teaching the language from scratch. If you want to learn C#, I recommend C# in Depth, 4th ed., by Jon Skeet (Manning, 2019), and Code Like a Pro in C#, by Jort Rodenburg (Manning, 2021). One big advantage of ASP.NET Core and.NET 7 over.NET Framework is that they enable you to develop and run on any platform. With.NET 7 you can build and run the same application on Mac, Windows, and Linux, and even deploy to the cloud using tiny container deployments. Built with containers in mind Traditionally, web applications were deployed directly to a server or, more recently, to a virtual machine. Virtual machines allow operating systems to be installed in a layer of virtual hardware, abstracting away the underlying hardware. This approach has several advantages over direct installation, such as easy maintenance, deployment, and recovery. Unfortunately, virtual machines are also heavy, in terms of both file size and resource use. This is where containers come in. Containers are far more lightweight and don’t have the overhead of virtual machines. They’re built in a series of layers and don’t require you to boot a new operating system when starting a new one, so they’re quick to start and great for quick provisioning. Containers (Docker in particular) are quickly becoming the go-to platform for building large, scalable systems. Containers have never been a particularly attractive option for ASP.NET applications, but with ASP.NET Core,.NET 7, and Docker for Windows, all that is changing. A lightweight ASP.NET Core application running on the cross-platform.NET 7 framework is perfect for thin container deployments. You can learn more about your deployment options in chapter 27. In addition to running on each platform, one of the selling points of.NET is your ability to write and compile only once. Your application is compiled to Intermediate Language (IL) code, which is a platform-independent format. If a target system has the.NET 7 runtime installed, you can run compiled IL from any platform. You can develop on a Mac or a Windows machine, for example, and deploy exactly the same files to your production Linux machines. This compile-once, run-anywhere promise has finally been realized with ASP.NET Core and.NET 7. TIP You can go one step further and package the.NET runtime with your app in a so-called self-contained deployment (SCD). This way, you can deploy cross-platform, and the target machine doesn’t even need.NET installed. With SCDs, the generated deployment files are customized for the target machine, so you’re no longer deploying the same files everywhere in this case. Many of the web frameworks available today use similar well- established design patterns, and ASP.NET Core is no different. Ruby on Rails, for example, is known for its use of the MVC pattern; Node.js is known for the way it processes requests using small discrete modules (called a pipeline); and dependency injection is available in a wide variety of frameworks. If these techniques are familiar to you, you should find it easy to transfer them to ASP.NET Core; if they’re new to you, you can look forward to using industry best practices! NOTE Design patterns are solutions to common software design problems. You’ll encounter a pipeline in chapter 4, dependency injection in chapters 8 and 9, and MVC in chapter 19. Whether you’re new to web development generally or only with.NET, ASP.NET Core provides a rich set of features with which you can build applications but doesn’t overwhelm you with concepts, as the legacy ASP.NET framework did. On the other hand, if you’re familiar with.NET, it’s worth considering whether now is the time to take a look at ASP.NET Core. If you’re a.NET Framework developer creating a new application If you’re already a.NET Framework developer, you’ve likely been aware of.NET Core and ASP.NET Core, but perhaps you were wary about jumping in too soon or didn’t want to hit the inevitable “version 1” problems. The good news is that ASP.NET Core and.NET are now mature, stable platforms, and it’s absolutely time to consider using.NET 7 for your new apps. As a.NET developer, if you aren’t using any Windows-specific constructs such as the Registry, the ability to build and deploy cross-platform opens the possibility for cheaper Linux hosting in the cloud, or for developing natively in macOS without the need for a virtual machine..NET Core and.NET 7 are inherently cross-platform, but you can still use platform-specific features if you need to. Windows- specific features such as the Registry and Directory Services, for example, can be enabled with a Compatibility Pack that makes these APIs available in.NET 5+. They’re available only when running.NET 5+ in Windows, not Linux or macOS, so you need to take care that such applications run only in a Windows environment or account for the potential missing APIs. TIP The Windows Compatibility Pack is designed to help port code from.NET Framework to.NET Core/.NET 5+. See http://mng.bz/2DeX. The hosting model for the previous ASP.NET framework was a relatively complex one, relying on Windows IIS to provide the web-server hosting. In a cross-platform environment, this kind of symbiotic relationship isn’t possible, so an alternative hosting model has been adopted—one that separates web applications from the underlying host. This opportunity has led to the development of Kestrel, a fast, cross-platform HTTP server on which ASP.NET Core can run. Instead of the previous design, whereby IIS calls into specific points of your application, ASP.NET Core applications are console applications that self-host a web server and handle requests directly, as shown in figure 2.6. This hosting model is conceptually much simpler and allows you to test and debug your applications from the command line, though it doesn’t necessarily remove the need to run IIS (or the equivalent) in production. ASP.NET Core and reverse proxies You can expose ASP.NET Core applications directly to the internet so that Kestrel receives requests directly from the network. That approach is fully supported. It’s more common, however, to use a reverse proxy between the raw network and your application. In Windows, the reverse-proxy server typically is IIS; in Linux or macOS, it might be NGINX, HAProxy, or Apache. There’s even an ASP.NET Core-based reverse proxy library called YARP (https://microsoft.github.io/reverse-proxy) that you can use to build your own reverse proxy. A reverse proxy is software responsible for receiving requests and forwarding them to the appropriate web server. The reverse proxy is exposed directly to the internet, whereas the underlying web server is exposed only to the proxy. This setup has several benefits, primarily security and performance for the web servers. You may think that having a reverse proxy and a web server is somewhat redundant. Why not have one or the other? Well, one benefit is the decoupling of your application from the underlying operating system. The same ASP.NET Core web server, Kestrel, can be cross-platform and used behind a variety of proxies without putting any constraints on a particular implementation. Alternatively, if you wrote a new ASP.NET Core web server, you could use it in place of Kestrel without needing to change anything else about your application. Another benefit of a reverse proxy is that it can be hardened against potential threats from the public internet. Reverse proxies are often responsible for additional aspects, such as restarting a process that has crashed. Kestrel can remain a simple HTTP server, not having to worry about these extra features, when it’s used behind a reverse proxy. You can think of this approach as being a simple separation of concerns: Kestrel is concerned with generating HTTP responses, whereas the reverse proxy is concerned with handling the connection to the internet. Figure 2.6 The difference between hosting models in ASP.NET (top) and ASP.NET Core (bottom). In the previous version of ASP.NET, IIS is tightly coupled with the application. The hosting model in ASP.NET Core is simpler; IIS hands off the request to a self-hosted web server in the ASP.NET Core application and receives the response but has no deeper knowledge of the application. NOTE By default, when running in Windows, ASP.NET Core runs inside IIS, as shown in figure 2.6, which can provide better performance than the reverse-proxy version. This is primarily a deployment detail and doesn’t change the way you build ASP.NET Core applications. Changing the hosting model to use a built-in HTTP web server has created another opportunity. Performance has been something of a sore point for ASP.NET applications in the past. It’s certainly possible to build high-performing applications— Stack Overflow (https://stackoverflow.com) is a testament to that fact—but the web framework itself isn’t designed with performance as a priority, so it can end up being an obstacle. To make the product competitive cross-platform, the ASP.NET team focused on making the Kestrel HTTP server as fast as possible. TechEmpower (https://www.techempower.com/benchmarks) has been running benchmarks on a wide range of web frameworks from various languages for several years now. In round 20 of the plain-text benchmarks, TechEmpower announced that ASP.NET Core with Kestrel was among the 10 fastest of more than 400 frameworks tested!3 Web servers: Naming things is hard One difficult aspect of programming for the web is the confusing array of often-conflicting terminology. If you’ve used IIS, for example, you may have described it as a web server or possibly a web host. Conversely, if you’ve ever built an application with Node.js, you may have also referred to that application as a web server. Or you may have called the physical machine on which your application runs a web server. Similarly, you may have built an application for the internet and called it a website or a web application, probably somewhat arbitrarily based on the level of dynamism it displayed. In this book, when I say web server in the context of ASP.NET Core, I’m referring to the HTTP server that runs as part of your ASP.NET Core application. By default, this server is the Kestrel web server, but that’s not a requirement. It’s possible to write a replacement web server for Kestrel if you so desire. The web server is responsible for receiving HTTP requests and generating responses. In the previous version of ASP.NET, IIS took this role, but in ASP.NET Core, Kestrel is the web server. I’ll use the term web application in this book to describe ASP.NET Core applications, regardless of whether they contain only static content or are dynamic. Either way, these applications are accessed via the web, so that name seems to be the most appropriate. Many of the performance improvements made to Kestrel came not from the ASP.NET team members themselves, but from contributors to the open-source project on GitHub (https://github.com/dotnet/aspnetcore). Developing in the open means that you typically see fixes and features make their way to production faster than you would for the previous version of ASP.NET, which was dependent on.NET Framework and Windows and, as such, had long release cycles. By contrast,.NET 5+ and hence ASP.NET Core are designed to be released in small increments. Major versions will be released on a predictable cadence, with a new version every year and a new LTS version released every two years (http://mng.bz/1qrg). In addition, bug fixes and minor updates can be released as and when they’re needed. Additional functionality is provided in NuGet packages independent of the underlying.NET 5+ platform. NOTE NuGet is a package manager for.NET that enables you to import libraries into your projects. It’s equivalent to Ruby Gems, npm for JavaScript, or Maven for Java. To enable this approach to releases, ASP.NET Core is highly modular, with as little coupling to other features as possible. This modularity lends itself to a pay-for-play approach to dependencies, where you start with a bare-bones application and add only the libraries you require, as opposed to the kitchen-sink approach of previous ASP.NET applications. Even MVC is an optional package! But don’t worry—this approach doesn’t mean that ASP.NET Core is lacking in features, only that you need to opt into them. Some of the key infrastructure improvements include Middleware pipeline for defining your application’s behavior Built-in support for dependency injection Combined UI (MVC) and API (web API) infrastructure Highly extensible configuration system Standardized, extensible logging system Uses asynchronous programming by default for built-in scalability on cloud platforms Each of these features was possible in the previous version of ASP.NET but required a fair amount of additional work to set up. With ASP.NET Core, they’re all there, ready and waiting to be connected. Microsoft fully supports ASP.NET Core, so if you want to build a new system, there’s no significant reason not to use it. The largest obstacle you’re likely to come across is wanting to use programming models that are no longer supported in ASP.NET Core, such as Web Forms or WCF Server, as I’ll discuss in the next section. I hope that this section whetted your appetite to use ASP.NET Core for building new applications. But if you’re an existing ASP.NET developer considering whether to convert an existing ASP.NET application to ASP.NET Core, that’s another question entirely. Converting an existing ASP.NET application to ASP.NET Core By contrast with new applications, an existing application presumably already provides value, so there should always be a tangible benefit to performing what may amount to a significant rewrite in converting from ASP.NET to ASP.NET Core. The advantages of adopting ASP.NET Core are much the same as those for new applications: cross-platform deployment, modular features, and a focus on performance. Whether the benefits are sufficient will depend largely on the particulars of your application, but some characteristics make conversion more difficult: Your application uses ASP.NET Web Forms. Your application is built with WCF. Your application is large, with many advanced MVC features. If you have an ASP.NET Web Forms application, attempting to convert it directly to ASP.NET Core isn’t advisable. Web Forms is inextricably tied to System.Web.dll and IIS, so it will likely never be available in ASP.NET Core. Converting an application to ASP.NET Core effectively involves rewriting the application from scratch, not only shifting frameworks, but also potentially shifting design paradigms. All is not lost, however. Blazor server provides a stateful, component-based application that’s similar to the Web Forms application model. You may be able to gradually migrate your Web Forms application page by page to an ASP.NET Core Blazor server application.4 Alternatively, you could slowly introduce web API concepts into your Web Forms application, reducing the reliance on legacy Web Forms constructs such as ViewState, with the goal of ultimately moving to an ASP.NET Core web API application. Windows Communication Foundation (WCF) is only partially supported in ASP.NET Core. It’s possible to build client-side WCF services using the libraries provided by ASP.NET Core (https://github.com/dotnet/wcf) and to build server-side WCF services by using the Microsoft-supported community-driven project CoreWCF.5 These libraries don’t support all the APIs available in.NET Framework WCF (distributed transactions and some message security formats, for example), so if you absolutely need those APIs, it may be best to avoid ASP.NET Core for now. TIP If you like WCF’s contract-based RPC-style of programming but don’t have a hard requirement for WCF itself, consider using gRPC instead. gRPC is a modern RPC framework with many concepts that are similar to WCF, and it’s supported by ASP.NET Core out of the box (http://mng.bz/wv9Q). If your existing application is complex and makes extensive use of the previous MVC or web API extensibility points or message handlers, porting your application to ASP.NET Core may be more difficult. ASP.NET Core is built with many features similar to the previous version of ASP.NET MVC, but the underlying architecture is different. Several of the previous features don’t have direct replacements, so they’ll require rethinking. The larger the application is, the greater the difficulty you’re likely to have converting your application to ASP.NET Core. Microsoft itself suggests that porting an application from ASP.NET MVC to ASP.NET Core is at least as big a rewrite as porting from ASP.NET Web Forms to ASP.NET MVC. If that suggestion doesn’t scare you, nothing will! If an application is rarely used, isn’t part of your core business, or won’t need significant development in the near term, I suggest that you don’t try to convert it to ASP.NET Core. Microsoft will support.NET