Book Image

ASP.NET Core 5 for Beginners

By : Andreas Helland, Vincent Maverick Durano, Jeffrey Chilberto, Ed Price
Book Image

ASP.NET Core 5 for Beginners

By: Andreas Helland, Vincent Maverick Durano, Jeffrey Chilberto, Ed Price

Overview of this book

ASP.NET Core 5 for Beginners is a comprehensive introduction for those who are new to the framework. This condensed guide takes a practical and engaging approach to cover everything that you need to know to start using ASP.NET Core for building cloud-ready, modern web applications. The book starts with a brief introduction to the ASP.NET Core framework and highlights the new features in its latest release, ASP.NET Core 5. It then covers the improvements in cross-platform support, the view engines that will help you to understand web development, and the new frontend technologies available with Blazor for building interactive web UIs. As you advance, you’ll learn the fundamentals of the different frameworks and capabilities that ship with ASP.NET Core. You'll also get to grips with securing web apps with identity implementation, unit testing, and the latest in containers and cloud-native to deploy them to AWS and Microsoft Azure. Throughout the book, you’ll find clear and concise code samples that illustrate each concept along with the strategies and techniques that will help to develop scalable and robust web apps. By the end of this book, you’ll have learned how to leverage ASP.NET Core 5 to build and deploy dynamic websites and services in a variety of real-world scenarios.
Table of Contents (19 chapters)
1
Section 1 – Crawling
7
Section 2 – Walking
12
Section 3 – Running

Explaining ASP.NET Core

The first version of .NET was released in 2002, so it doesn't sound impressive that we're getting at version 5 since it's been 18 years. However, it is slightly more complicated than that, both with the numbering system and due to various sidetracks. A complete history could possibly be a book on its own, but to understand where we are now, we will take you on a short walk down memory lane.

When .NET came on the scene, there were a couple of options available to you for choosing a programming language depending on your scenario. Visual Basic was popular for introductory type programming since it was, as the name implies, visually oriented and easy to get started with. However, VB wasn't great for writing complex applications at scale with high performance. Windows itself was mostly written in C and C++ and was the preferred route for professional-grade software. While these languages were (and still are) highly capable, they were notorious for allowing the programmer to shoot themselves in the foot due to things such as making the coder responsible for memory management and other low-level operations that were hard to debug and troubleshoot.

In parallel with the language implementations offered directly from Microsoft, Sun Microsystems released Java as a solution to these challenges. Instead of producing native code, the tooling produced managed code that abstracted memory management and made things easier. The syntax of the language was in the C++ style, so transitioning from C++ was easy for developers looking to make the switch to Java. It was also a stated goal that the code written should be portable to multiple platforms. This was enabled by a Java Virtual Machine (JVM), which was installed to execute on a given system.

Managed versus unmanaged code

Programming languages have evolved over the years. Where the first computers were programmed by physically turning switches and levers, you can now write instructions where even non-programmers are able to figure out what some of the commands mean.

One often refers to the relative closeness to the computer's native language (zeros and ones) by referring a language as low-level (close) or high-level (abstract). At the lowest level, you have languages like assembler language, which theoretically have the least overhead (provided you can find highly talented programmers), but in addition to being complex, an assembler language is not portable across different CPU architectures. C# leans more towards the other end of the spectrum, with more natural language and many of the "hard things" are hidden from the programmer. And there are also languages that are even more high-level, such as Scratch (a block-based language), targeted at kids wanting to get into programming. (There is no formal definition of low versus high.)

One of the mechanisms C# uses to achieve this is by having an intermediate layer (for .NET this is the Common Language Runtime) that translates your code in real time to the underlying machine code understood by your computer. This means that the programmer does not need to handle allocating and releasing memory, does not interfere with other program's processes, and so on, and generally does a lot of the grunt work. To cater to the developers and enable them to create applications with a minimal re-learning experience, .NET was in demand for these platforms, but .NET was not built to run without the desktop components available.

The concept is not new to or unique for C#, and it is also the concept used in Java. Originally, it was conceived back in the IBM mainframe era. On personal computers, it was initially challenging since managed code will always have an overhead due to the translation that occurs, and on resource-constrained computers (when .NET 1.0 was released), it can run slow. Newer computers handle this much more efficiently, and .NET has been optimized over the years, so for most applications, it is not much of an issue any longer if the code is managed or not.

Introducing the .NET platform

Microsoft took inspiration from Java, as well as their learnings from the ecosystem they provided, and came up with .NET. The structure of the platform is displayed in Figure 1.2.

.NET was also based on managed code and required a Common Language Runtime (CLR) to be installed to execute. The C# language was released in the same time frame, but .NET also supported Visual Basic and J#, highlighting that it was a more generic framework. Other programming languages that required extra software to be installed for running applications had the challenge of getting end users to install it themselves. Microsoft, on the other hand, had the advantage of supplying the operating system, thus giving them the option of including .NET as a pre-installed binary.

Figure 1.2 – The .NET platform

Figure 1.2 – The .NET platform

.NET Framework was, as the second part of the name implies, intended to be more complete than dictating that a certain language must be used and can only be used for specific types of applications, so it was modular by nature. If you wanted to create an application running as a Windows service, you needed other libraries than an application with a graphical user interface, but you could do it using the same programming language.

The original design of .NET Framework did not technically exclude running on other operating systems than Windows, but not seeing the incentive to provide it for Linux and Apple products, it quickly took dependencies on components only available on desktop Windows.

While Windows ran nicely on x86-based PCs, it did not run on constrained devices. This led Microsoft to develop other versions of Windows such as Windows Mobile for smartphones, Windows CE for things such as ATMs and cash registers, and so on. To cater to the developers and enable them to create applications with a minimal re-learning experience, .NET was in demand for these platforms, but .NET was not built to run without the desktop components available. The result was .NET being split into multiple paths where you had .NET Compact Framework for smartphones and tablets and .NET Micro Framework for Arduino-like devices.

Essentially, if you were proficient in C#, you could target millions of devices in multiple form factors. Unfortunately, it was not always that easy in the real world.

The libraries were different. If you wrote your code on the desktop and wanted to port it to your mobile device, you had to find out how to implement functionality that was not present in the Compact version of .NET. You could also run into confusing things such as an XML generator being present on both platforms; even though they looked similar, the output generated was not.

.NET Framework was released along with Windows operating systems, but often this was not the newest version, so you still had to install updates for it to work or install additional components.

Even worse was when you had to run multiple versions of .NET on the same machine, where it was frequently the case that these would not play nicely with each other and you had to make sure that your application called into the right version of the libraries. While originating with C++ on Windows, the challenge carried over to .NET and you may have heard this being referred to as "DLL Hell."

This book uses the term ASP in the title as well (ASP.NET). ASP has a track of its own in this history lesson. In the olden days of Windows NT, rendering web pages was not a core component for a server but could be installed through an add-on called Active Server Pages (ASP for short) on top of Internet Information Server. When .NET was released, this was carried over as ASP.NET. Much like the base components of .NET, this has also seen multiple iterations in various forms over the years. Initially, you had ASP.NET Web Forms, where you wrote code and scripts that the engine rendered as HTML for the output. In 2009, the highly influential ASP.NET MVC was released, implementing the Model-View-Controller pattern, which still lives on.

Patterns

A pattern is a way to solve a common problem in software. For instance, if you have an application for ordering products in an online store, there is a common set of objects and actions involved. You have products, orders, and so on commonly stored in a database. You need methods for working with these objects – decrease the stock when a customer orders a product, applying a discount due to the customer having a purchase history. You need something visible on the web page where the customer can view the store and its products and perform actions.

This is commonly implemented in what is called the Model-View-Controller (MVC) pattern.

The products and orders are described as Models. The actions performed, such as decreasing the number, retrieving pricing info, and so on are implemented in Controllers. The rendering of output visible to the end user, as well as accepting input from end users, is implemented in Views. We will see this demonstrated in code later in this book.

Patterns cover a range of problems and are often generic and independent of the programming language they are implemented in.

This book will touch upon patterns applicable to ASP.NET Core applications, but will not cover patterns in general.

Confusingly, there were other web-based initiatives launched separately, for instance, Silverlight, which ran as a plugin in the browser. The thinking was that since a browser restricted code to a sandbox, this could act as a bridge to accessing features usually only available outside a browser. It didn't become a hit, so although you can still make it run it is considered deprecated.

With Windows 8's app model, you could write apps installable on the device using HTML for the UI that were not directly compatible with an actual web app. Relying on the Windows Store for distribution, it was hampered by the fact that not all users upgrade immediately to new Windows versions, and developers mostly preferred reaching the largest audience instead.

At the same time as Windows 8 and .NET 4.5 were launched, Microsoft came up with .NET Standard. This is a set of APIs that are in the Base Class Library for any .NET stack. This meant that certain pieces of code would work equally well in a desktop Windows application as a mobile app intended for Windows Phone. This did not prohibit the use of platform-specific additions on top, but it was easier to achieve a basic level of portability for your code. This did not mean you achieved write once run everywhere use cases but was the start of the cross-platform ecosystem we are seeing now.

Microsoft was mainly concerned with growing the Windows ecosystem, but outside the company, the Mono project worked on creating an open source version of .NET that could run applications on Linux. The Linux effort did not initially take off, but when the creator, Miguel de Icaza, started the company Xamarin, focusing on using this work to make .NET run on iOS and Android devices, it gained traction. Much like the reduced versions of .NET, it was similar to what you had on the desktop, but not identical.

Outside the .NET sphere, technology has changed over the years. In 2020, you can get a mobile device more powerful than a 2002 desktop. Apple devices are everywhere in 2020 whereas in 2002 it was still a couple of years before the iPhone and iPad would be launched. Another significant thing was that in 2002, code written by Microsoft would primarily be read and updated by their employees. Open source was not a thing coming out of Redmond.

These trends were tackled in different ways. Microsoft started open sourcing pieces of .NET back in 2008, though it was not the complete package, and there were complaints around the chosen license, which some felt was only semi-open source.

Fast forward to 2016 when .Net Core was announced. .NET was on version 4.6.2 at the time and .NET Core started with 1.0. From that point in time, the original .NET has been referred to as "Classic" .NET.

The mobile platform issue partly resolved itself by Windows Mobile/Windows Phone failing in the market. Xamarin was acquired, also in 2016, which meant that mobile meant the operating systems were from Google and Apple.

Microsoft had by this time committed fully to open source and even started accepting outside contributions to .NET. The design of the language is still stewarded by Microsoft, but the strategy is out in the open and non-Microsoft developers make considerable contributions.

Microsoft learned from the past and recognized that there would not be a big bang shift towards using .NET Core instead of .NET Classic. Regardless of whether developers would agree the new version was better or not, it was simply not possible for everyone to rewrite their existing code in a short matter of time, especially since there were APIs not available in the initial version of .NET Core.

The .NET Standard message was re-iterated. You could write code in .NET 4.6 targeting .NET Standard 1.3 and this would be usable in .NET Core 1.0 as well. The intent was that this could be used for a migration strategy where you moved code piece by piece into a project compatible with .NET Standard and left the non-compatible code behind while writing new code to work with .NET Core.

Unfortunately, it was hard for people to keep track of all the terms – .NET, .NET Classic, .NET Core, .NET Standard, and all the corresponding version numbers, but it is still a viable strategy mixing these to this day.

.NET Core was, as stated, introduced with a version number of 1.0. Since then it has increased the numbers, reaching 3.1. At first glance, this means that it does not sound logical that the next version would be called .NET Core 5. There are three main reasons why this numbering was abandoned:

  • .NET Core 4.x could easily be mixed up with .NET 4.x.
  • Since there is a .NET 4.x (non-Core), the next major number of this would be 5.
  • To illustrate how the two paths "merge," they meet up at version 5. To help avoid confusion, "Core" was dropped from the version name.

.NET Classic has reached the end of its life when it comes to new versions, so going forward, (after .NET 5), the naming will be .NET 6, .NET 7, and so on with .NET Core as the foundational framework.

.NET Classic will not be unsupported or deprecated soon, so existing code will continue to work, but new functionality and investments will not be made.

Supportability strategy

Traditional .NET Classic versions have enjoyed long supportability although not with a fixed lifetime, instead depending on service pack releases and the operating system it was released with.

With .NET Core 2.1, Microsoft switched to a model common in the Linux ecosystem with versions that are dubbed LTS (Long-Term Support) and non-LTS. An LTS release will have 3 years of support, where non-LTS only has one year. Minor versions are expected to be released during the support window, but the end date is set when the major version is released.

Figure 1.3 shows the .NET release timeline, focusing on its supportability schedule.

Figure 1.3 – .NET supportability schedule

Figure 1.3 – .NET supportability schedule

Obviously, we can't guarantee a new release will be deployed every year, but that's the current plan. From .NET Core 3.1, the planned cycle is a new version in November of every year, and LTS every other year. .NET 5 was released in November 2020 as a non-LTS release. .NET 6 is targeted as an LTS release in November 2021.

This does not mean that code written in an unsupported version breaks or stops working, but security patches will not be issued, and libraries will not be maintained for older runtimes, so plan for upgrades accordingly. (Microsoft has a track record of providing guidance for how to update code to newer versions.)

It has at times felt like a bumpy ride, but unless you must deal with legacy systems, the current state of affairs is more concise than it has been in a long time.

This section was mostly a history lesson on how we got to where we are now. In the next section, we will do a friendly walk-through of a basic web application based on C# code.