My new book, ASP.NET Core in Action, Second Edition is available now! In this post I describe a little bit about the process of updating the book, talk about what's changed from the first version (and why), and describe the table of contents in brief.
If you'd like to see some of the content of the book, I have a couple of samples taken from the book in previous posts:
You can also use Manning's LiveBook functionality to read snippets of the book online.
I started writing the first edition of the book, ASP.NET Core in Action, back in August of 2016, right after the release of .NET Core 1.0 (in June 2016). As anyone who's gone through it will know, the process of planning, writing, and refining a book is a long one. ASP.NET Core in Action was finally published in June 2018.
In those two years from inception to publishing, the book had gone through many changes, not least in part due to the large changes that took place in .NET Core itself. During that time .NET Core had moved from version 1.0, through 1.1, to version 2.0 and even 2.1! .NET Standard was introduced. Microsoft's Current vs LTS support policy was introduced.
I managed to keep the book up to date through these changes, with the book releasing shortly after .NET Core 2.1 was released, but at that point, things were set in stone. Luckily for me, the biggest breaking changes occurred from 1.x to 2.x, so I covered those in the book. However, ASP.NET Core 3.x introduced various features that the first edition didn't cover. To name a few:
- Endpoint routing, changed the way we build middleware pipelines.
- ASP.NET Core was re-platformed onto the generic host, making it easier to build non-HTTP applications with ASP.NET Core.
- Razor Pages continued to grow in popularity as the idiomatic way to create server-side rendered page-based applications.
In January of 2020, some time after .NET Core 3.1 had been released and 6 months since the announcement of .NET 5, I reached out to Manning to see if they would be interested in a second edition of the book. The goal was to target the release of the second edition of the book shortly after the .NET 5.0 release. I'm happy to say we achieved that, and the book was published in March of 2021.
I highlighted the headline changes in the previous section, but I'll describe those changes in a little more detail here, along with other changes I made. The book is over 100 pages longer than the first edition (a whopping 832 pages, compared to 712 pages in the first edition), but there have been some larger structural changes too.
The biggest change in the first part of the book is the focus on Razor Pages. In the first edition, I mentioned Razor Pages, but didn't focus on them. This was partially due to timing (I had largely written the first half of the book before Razor Pages were released with .NET Core 2.0), but I also wasn't sure if they were going to be popular, or if I really liked them.
Since then, I've adjusted my view on Razor Pages, and I consider them the way to do page-based server-rendered web applications in ASP.NET Core. In many ways they're no different to the traditional MVC controllers and views you'll be used to if you're a "classic" ASP.NET developer; you're still separating view/controller/business logic. But they make your code base far more cohesive and easier to navigate.
I know many people still aren't convinced by this argument, but most of the reasons I've seen against them are based on "gut feel" or straw man arguments. You can still use the MVC pattern with Razor Pages, as I discuss in a previous post (and in the book).
Consequently, chapters 4-8 of the book have been rewritten to focus on Razor Pages, instead of the "classic" controllers and views approach. This required a lot of rethinking and restructuring of the content, but I believe the book now closer matches the approach I think developers should be taking, especially for new applications.
Another big change in ASP.NET Core was introduced in .NET Core 3.0, where we moved to use endpoint routing by default. This was a breaking change for applications (though you could continue to use the "old" approach if necessary), and in my experience can be the source of some confusion. Instead of having a single "MVC" middleware, we now have two pieces of middleware:
EndpointMiddleware, which is where you define the "endpoints" (MVC controllers, Razor Pages, health check endpoints) in your application. It's responsible for executing and endpoint.
EndpointRoutingMiddleware, which is responsible for choosing which endpoint to execute for a request.
I've found this split is quite difficult for newcomers to understand, but it can be extremely powerful. By splitting the middleware in two, you can insert middleware between them, enabling you to take actions based on which endpoint will be executed, before it does.
Endpoint routing also makes it easier to create "lightweight" endpoints, that use all the power of routing and route templates, without requiring MVC or Razor Pages.
Teaching endpoint routing in the book required a range of updates:
- Significant updates to chapter 5, on routing, as you might expect!
- Additions to chapter 19, creating custom components, showing how to create an endpoint routing component.
- Showing how to create simple lightweight APIs using the
WriteJsonAsyncAPIs available in .NET 5.
- I also took the opportunity to move away from teaching "conventional" routing, and focused on the "attribute" routing used by both API Controllers and Razor Pages. Given the focus of the book (and my personal experience of conventional routing), this seemed to simplify things.
If you like conventional routing, then the good news is that the first edition of my book covers conventional routing, and its interactions with attribute routing. Even better, if you buy the second edition of my book, you get a copy of the first edition too, absolutely free!
Endpoint routing is one of the biggest breaking changes in moving from ASP.NET Core 2.0 to 3.0, and is one of the hardest to get your head around. Frankly, it was the biggest motivation for me to update the book. But there are some other nice features that I wanted to include too.
[ApiController] attribute was introduced in ASP.NET Core 2.1, and provides a way of applying various conventions to controllers that are used to build HTTP APIs, for example:
400Bad Request responses when model validation fails
- Parameter binding source inference
- Problem Details support
If you're building HTTP APIs then this attribute is well worth looking at, so I included a new section in Chapter 9 about
[ApiController], the benefits it brings, and what it leaves out.
ASP.NET Core 2.1 introduced
IHttpClientFactory as a dependency-injection focused approach to solving some of the long-standing issues with
HttpClient. I added a new chapter in the second edition of the book, Chapter 21, which describes the problems with
HttpClient, and how
IHttpClientFactory addresses them. I discuss named and typed clients, show how to use Polly to add transient fault tolerance, and show how to build a custom
The "generic" or
IHost host support refers to the fact that ASP.NET Core 3.0 and 5.0 have been rearchitected so that you can use them for non-HTTP workloads. This was technically possible in ASP.NET Core 2.1, but I wasn't a fan of the implementation (though I totally understood and agreed with the reason for it).
I suspect one of the most common uses for the generic host support is for running message-queue processors. These are applications that don't receive web traffic, but instead process messages from RabbitMQ, Kafka, or other message queue. Using
IHost means you can still use some of the features of ASP.NET Core, like the configuration or dependency injection systems, even though you don't handle web traffic.
I added a new chapter to the book to discuss this approach, Chapter 22, in which I describe how to create background services using
IHostedService and how to create services using
IHost. I also describe how to use the open-source Quartz.NET library to add more advanced scheduling capabilities.
Quartz.NET is just one of the open-source libraries I mention or demonstrate in the book. I think I'll do a separate post highlighting all the projects I discuss, partly as a way to say thank you to everyone who's worked on them!
There are obviously many smaller or self-contained changes I made to the second edition, too many to mention here. I definitely experienced some (self-inflicted) scope-creep during the update, but I think the book is better for it in the end!
I've already covered some of the changes in the second edition, but I figured it would probably be useful to give an overview of the whole book. You can read the full table of contents at manning.com, as well as look inside at samples, but I thought I'd provide a high level overview of each chapter here:
Part 1 Building your first applications
- Chapter 1. Getting started with ASP.NET Core An introduction to ASP.NET Core, what it is, why you should care, and an overview of how it works.
- Chapter 2. Your first application A look at the default Razor Pages templates, introducing each of the files and components, and what they're for.
- Chapter 3. Handling requests with the middleware pipeline The middleware pipeline, why it's important, and how it works. Using error handling middleware as an example for understanding the pipeline.
- Chapter 4. Creating a web site with Razor Pages An introduction to Razor Pages, the MVC design pattern, and Razor Page handlers
- Chapter 5. Mapping URLs to Razor Pages using routing An in depth look at using routing to map incoming URLs to endpoints (focusing on Razor Pages). Exploring the route template syntax and how to generate URLs.
- Chapter 6. The binding model: retrieving and validating user input Understanding model binding and validation.
- Chapter 7. Rendering html using Razor views A look at the Razor markup language, how to use C# in Razor (carefully!), as well as layouts.
- Chapter 8. Building forms with tag helpers Exploring the common tag helpers used to build typical web apps, such as the form Tag Helpers and anchor Tag Helpers, as well has helpers such as the
- Chapter 9. Creating a Web API for mobile and client applications using MVC Building HTTP APIs using API controllers, the
[ApiController]attribute, content negotiation, and adding output formatters.
Part 2 Building complete applications
- Chapter 10. Service configuration with dependency injection An introduction to dependency injection and how it works in ASP.NET Core. Understanding lifetimes and how to register your own services.
- Chapter 11. Configuring an ASP.NET Core application How to use the configuration system in ASP.NET Core to load configuration from multiple sources, how to store secrets safely, and how to bind configuration to strongly typed models.
- Chapter 12. Saving data with Entity Framework Core An introduction to using EF Core to interact with a database. For a more detailed look, I suggest looking at Jon P. Smith's EF Core in Action, Second Edition.
- Chapter 13. The MVC and Razor Pages filter pipeline A detailed look at the MVC and Razor Page filters, how they all fit together, when to use them, and how to create your own filters.
- Chapter 14. Authentication: adding users to your application with Identity Understanding the ASP.NET Core authentication and authorization model. Adding ASP.NET Core Identity to an application, using and customising the default Identity UI.
- Chapter 15. Authorization: securing your application Understanding declarative and imperative authorization in ASP.NET Core. Creating custom authorization policies and requirements. Controlling the UI based on authorization concerns.
- Chapter 16. Publishing and deploying your application Understanding the ASP.NET Core hosting model and publishing your application for production use. Optimising client-side assets using BundlerMinifier.
Part 3 Extending your applications
- Chapter 17. Monitoring and troubleshooting errors with logging Using the ASP.NET Core logging APIs to manage your logs. Adding logging providers, controlling log verbosity, and using structure logging.
- Chapter 18. Improving your application’s security Adding HTTPS to your application and your options. Defending against XSS, CSRF, and various other attacks, and working with CORS.
- Chapter 19. Building custom components Building custom middleware components and branching middleware pipelines, creating custom endpoint middleware, handling complex configuration requirements, and using a third-party DI container.
- Chapter 20. Building custom MVC and Razor Pages components Creating custom Tag Helpers, view components, and validation attributes. Using a third-party validation framework instead of DataAnnotations attributes.
- Chapter 21. Calling remote APIs with IHttpClientFactory As discussed above, why
IHttpClientFactoryis necessary, how it works, creating named and typed clients, and using and creating custom
- Chapter 22. Building background tasks and services As discussed above, building background services with
IHostedService, building "headless" ASP.NET Core apps with
IHost, and creating scheduled tasks.
- Chapter 23. Testing your application An introduction to testing, how to test middleware and API controllers, and integration testing your whole application
- Appendix A: Preparing your development environment How to install ASP.NET Core and some of the IDEs and editor available
- Appendix B: Understanding the .NET ecosystem An overview of the .NET ecosystem, the history leading up the .NET 5, and a look at the future. Also the evolution and future of .NET Standard.
- Appendix C: Useful references A variety of links to posts, blogs, documentation, and videos I've found useful
Obviously this is a very brief overview of a hefty book, but hopefully it gives you a taste of what's included! One area of ASP.NET Core that I don't cover at all, as it's a huge topic on its own, is Blazor. Luckily Chris Sainty is working on Blazor in Action, which is available to purchase now, and is due for publication later this year!
ASP.NET Core in Action, Second Edition is available now, in both electronic and paperback form! In this post I gave an overview of some of the changes from the first edition of the book and why I made those changes, as well as an overview of the full table of contents. Remember, if you buy the second edition of the book (thank you! 🙂), you get an eBook version of the first version free!