18
.NET Core

WHAT IS .NET CORE?

This is probably at the heart of the most pressing questions on the minds of developers. Is it a replacement for the .NET Framework? Does this mean that .NET is going away? The answers aren’t nearly as dire as the casual developer might think.

The goal of .NET Core is to provide an execution platform that is capable of running on multiple operating systems. Applications that have been written against .NET Core can be executed on Windows (naturally) but also on macOS and Linux. It is also intended to be used in embedded scenarios, including the ever present IoT (Internet of Things). Yes, this might seem like a laundry list of targets, but the idea is to help developers minimize the changes that need to be made to their application as they migrate from platform to platform.

Now don’t get to thinking that .NET Core is a full implementation of the .NET Framework on these other platforms. It’s not. It is an implementation of the .NET Standard Library on multiple platforms. The .NET Standard Library defines the set of .NET APIs that are to be implemented on every platform that supports .NET. It is a subset of the .NET Framework. As a result, it’s not possible to run every .NET application on each of those platforms. However, application compatibility exists for Xamarin (https://xamarin.com) and Mono (http://www.mono-project.com) on the appropriate platforms.

From a development perspective, .NET Core applications can be developed in C# and F#, and plans are in the works to support Visual Basic as well. The SDK and compilers are provided for the different platforms, so it’s possible to develop applications on the platform for which they are targeted. For instance, you can create applications for the Mac on the Mac using Visual Studio Code.

In Visual Studio 2017, there are a number of different templates that are available to create .NET Core applications. They are:

  • Console Application: Creates a command-line application
  • Class Library: Creates a library that will be used in other .NET Core applications
  • Unit Test Project: Allows for unit testing of your projects using MSTest
  • xUnit Test Project: Allows for unit testing of your projects using xUnit
  • ASP.NET Core Empty: Creates an empty .NET Core application that is suitable for serving up a web site
  • ASP.NET Core Web App: Creates an ASP.NET MVC application
  • ASP.NET Core Web API: Creates an ASP.NET Web API application
  • Solution File: Creates an empty solution

As a brief interlude before getting into the ASP.NET Core application, you should be aware that much of what can be done with .NET Core can be done using command-line tools. For example, the following command line will create a new .NET Core Console application in the traditional Hello World style:

 dotnet new console -n HelloWorld -o src/HelloWorld 

The result, as seen when executed in the Developer Command Prompt for VS 2017, is as follows.

Content generation time: 99.6688 ms
The template "Console Application" created successfully.

Let’s finish up this Hello World example. Use the following commands to change the directory to the location of the generated source and see what it looks like.

cd src/HelloWorld
dir
03/25/2017  11:14 AM    <DIR>          .
03/25/2017  11:14 AM    <DIR>          ..
03/25/2017  11:13 AM               170 HelloWorld.csproj
03/25/2017  11:13 AM               180 Program.cs
               2 File(s)            350 bytes
               2 Dir(s)  229,216,518,144 bytes free

The last two steps are to restore the packages necessary to run the application and to run the application itself. The dotnet restore command retrieves the needed packages, while dotnet run executes the code. The result is as follows.

C:DemoHelloWorldsrcHelloWorld dotnet restore
  Restoring packages for C:DemoHelloWorldsrcHelloWorldHelloWorld.csproj...
  Generating MSBuild file C:DemoHelloWorldsrcHelloWorld obj
    HelloWorld.csproj.nuget.g.props.
  Generating MSBuild file C:DemoHelloWorldsrcHelloWorld obj
    HelloWorld.csproj.nuget.g.targets.
  Writing lock file to disk. Path: C:DemoHelloWorldsrcHelloWorld src
    HelloWorldobjproject.assets.json
  Restore completed in 2.41 sec for C:DemoHelloWorldsrcHelloWorld src
    HelloWorldHelloWorld.csproj.

  NuGet Config files used:
      C:UsersruceAppDataRoamingNuGetNuGet.Config
      C:Program Files (x86)NuGetConfigMicrosoft.VisualStudio.Offline.config

  Feeds used:
      https://api.nuget.org/v3/index.json
      C:Program Files (x86)Microsoft SDKsNuGetPackages

C:DemoHelloWorldsrcHelloWorld srcHelloWorld>dotnet run
Hello World!

WORKING WITH ASP.NET CORE

As much as it might pain you to acknowledge, ASP.NET is old. Really old. It was first released with .NET 1.0 in 2002. Friendster had 3 million users in 2002 and Facebook didn’t exist. Blockbuster turned down an opportunity to purchase Netflix. The iPod was a year old and the iPhone was but an idea. So much has changed, and not just in the consumer marketplace. The tools and techniques used to build web applications now are a far cry from .NET 1.0. And even ASP.NET MVC, a much more flexible development platform, is getting on in years.

But change for change’s sake is not a good enough reason to consider a different development and deployment pattern. So let’s consider what makes an ASP.NET Core application both different and worthwhile.

Architecturally, ASP.NET Core is a more modular framework than ASP.NET. ASP.NET is based on the System.Web library. And while there is a lot that is good in System.Web (everything from membership to cookies to Web Form controls), over time that particular assembly has become heavy. If you use one of these features, then the entire System.Web assembly must be included in your project. And in a world of lightweight and agile options, that is a potential problem.

The idea of modularity in ASP.NET Core applications is accomplished through packages. .NET Core includes, as the name suggests, just the core functionality that is likely to be used across different classes of applications. If you need functionality beyond that core, it can be made available to your application through the addition of packages that contain only that functionality. Need access to membership? No problem. Just add the membership package to your projects. And that’s all you’ll get. Your application is as small as you need for the functionality you use and no larger.

project.json versus csproj

ASP.NET Core is not completely new for Visual Studio 2017. Although only preview tooling was available when Visual Studio 2015 was released, enhancements were made to the .NET Core tools through a number of additional releases. This tooling used project.json as the container for project-related information.

In the abstract, there was nothing wrong with project.json. It was actually quite easy to understand and was supported within Visual Studio with IntelliSense capabilities. If you were creating .NET Core applications from scratch, then there were a lot of benefits that accrued from using project.json.

However, there were a couple of fatal flaws that eventually resulted in retiring project.json as the project format of choice. Probably the most influential was that MSBuild didn’t support it. As well, the migration of existing, monolithic projects to project.json would require a large amount of effort and would be fraught with the potential for errors. Both of these concerns resulted in the csproj format being selected as the format for future development efforts.

This isn’t a complete loss for people who fell in love with project.json. Microsoft has made some changes to the csproj format to help with some of the things that people loved about project.json. Probably the most useful is the fact that not every single file that is part of the project needs to be enumerated within the csproj file. Instead, wildcarding can be used to include files. This greatly helps reduce the number of merge conflicts that might otherwise occur when you are working with large teams.

Creating an ASP.NET Core Application

The basic mechanics of creating an ASP.NET Core application will be familiar to Visual Studio users. Start by selecting the File ➪ New ➪ Project menu option. The New Project dialog (shown in Figure 18-1) appears.

Snapshot of New Project dialog.

FIGURE 18-1

From the navigation list on the left, select the language of your choice (so long as your choice is Visual C #), and then select the .NET Core option to show the list of templates. Choose ASP.NET Core Web Application (.NET Core).

Alternatively, you can select the Web option from the navigation list and a list of Web templates. This includes the same ASP.NET Core Web Application (.NET Core) template, along with an ASP.NET Core Web Application (.NET Framework) template. The only difference is the runtime libraries supported by the project. The former uses the .NET Core runtime, allowing it to be deployed onto Linux or MacOS machines. The later can only be used on machines that support the .NET Framework (that is, Windows-based servers).

Regardless of the template that you decide to use, once you have provided a project name, the dialog shown in Figure 18-2 appears.

Snapshot of ASPNETCore App template.

FIGURE 18-2

In this dialog, you are selecting from a list of ASP.NET Core templates that provide slightly different starting points. The Empty project template creates just that: an empty project. You will need to add all of the files, both supporting and otherwise, yourself. The Web API and Web Application project templates provide a reasonable starting point for creating a Web API or a Web application, respectively.

If you select the Web Application as your starting point, the Change Authentication button in the lower right of the dialog becomes enabled. This allows you to configure the new project with the authentication method that you would like to use. The Change Authentication dialog (Figure 18-3) appears when you click the button.

Snapshot of Change Authentication dialog.

FIGURE 18-3

The authentication options that are available are:

  • No authentication: The project will be created with no authentication configured and no files related to configuration included.
  • Individual User Accounts: The project will be created with the assumption that you’re using user accounts specific to your project. This includes the traditional membership provider that ASP.NET developers have been using for years, as well as third-party authentication services like Facebook or Microsoft Live.
  • Work or School Accounts: The project is created assuming that you’re authenticating against a claims-based authentication service like Active Directory (either locally hosted or in Azure).
  • Windows Authentication: The project is created so the current Windows user will be used to provide authentication and authorization details. This option should only be used if you are creating a web application for use on an intranet.

Once you have finished identifying the specific template you want to use, with any of the additional information that is required, the project that is created will look similar to what you see in Figure 18-4.

Snapshot of Solution Explorer.

FIGURE 18-4

If this is your first time with an ASP.NET Core application, then there are a number of differences between this and an ASP.NET MVC application. And yet, there are also a couple of similarities to make sure you feel comfortable.

Let’s start with the similarities. You’ll notice that there is a Controllers folder that contains the controller classes. And the Views folder contains Razor (that is, the .CSHTML) files for the controllers. The files in this folder structure include the views that are shared across the different controllers.

Although the Controllers and Views folders do make up a large portion of any web application, that is pretty much the end of the similarities to an ASP.NET MVC application. To start, there is a wwwroot folder. This folder is actually the directory from which the content of the web application gets served up, at least during the development process. By default, there are subfolders called css, images, js, and lib. These folders contain the files that make up the default web application that is part of your chosen template.

There is a Dependencies node that is visible in the Solution Explorer. This node contains the different dependencies that are required by the application. With the template, there are three child nodes, one for each source of the dependency. The Bower node contains a list of the dependencies served by Bower. A more detailed description appears in the “Bower Package Manager” section later in this chapter. The NuGet node contains the list of packages that use the NuGet Package Manager to be delivered to the build process. More details on the NuGet functionality is found in the NuGet Package Manager section later in this chapter. And finally the SDK node contains the SDK files that are referenced by the application.

Beyond the wwwroot folder and the Dependencies node, there are a number of different files related to the application:

  • Appsettings.json: This contains the configuration information for the web application. To a certain extent, it replaces the connection string, AppSettings and custom configuration settings that were previously found in the web.config file.
  • Bower.json: The ASP.NET Core project templates uses Bower to deliver static content to the client. This file is used to configure the packages that are included in the project.
  • Bundleconfig.json: This is used to configure the bundling and minification that is performed by the build process.
  • Program.cs: While this might seem like a surprising file to appear in a Web application, it is used (as it always has been) as the starting point for the application. In the case of an ASP.NET Core application, it defines the process that will host the running web application and then starts it.
  • Startup.cs: This contains a class that runs at startup. In general, the purpose of the class is to pull configuration information from various sources, but it also has the ability to set up a number of different pipeline functions.

Also, under the Properties node, there is another configuration file called launchSettings.json. This file contains information that is used to set up the running web application. It includes, for example, the URL (including the port number), the type of authentication that is being used, and whether a browser should be launched at start.

So you can get a sense of what the Program and Startup classes do, the following is the code from the default template:

        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .UseApplicationInsights()
                .Build();

            host.Run();
        }

As you can see, the code itself is relatively straightforward. It creates an instance of the WebHostBuilder and then uses a number of its methods to define the behavior of the host. This includes where to find the content, which startup class to call, and whether Application Insights should be included. Once the instance has been configured, it is launched with a call to the Run method.

The Startup class is a little more wordy, but it also provides functionality to the web application at runtime, as well as at startup. The constructor for Startup (shown below) builds the configuration information.

        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false,
                  reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json",
                  optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

Here, you can see that the appsettings.json file that was mentioned earlier is being loaded, along with any environment-specific configuration. But alongside building the configuration information, the Startup class included logging capabilities, features based on development versus release settings, and MVC routes.

NUGET PACKAGE MANAGER

The ability to include third-party packages in your project is taken as a given. Without such capabilities, the development effort for practically any application would be gargantuan. However, including external assemblies is not without issues. Once you have downloaded the assembly to your machine, your application works. No problem. However, what about your colleagues? Do they need to download the application as well, and make sure that it’s in the same location relative to the project source code? And what happens when you check your project in? Do you include the foreign assembly? And how does the central build engine know where to find the referenced assembly?

As you can see, there are lots of questions, and none of the answers are very good. Into this maelstrom rides the NuGet Package Manager, known by most as just NuGet. NuGet is a tool that can be used from within Visual Studio, from a command line or through a build process. Its fundamental purpose is to retrieve the packages needed by your application from a central repository. To put that into the basic developer workflow, when you build your application, one of the tasks that takes place is that your machine checks to see if all of the required assemblies are available. If not, then NuGet goes to the NuGet package gallery and downloads the missing assemblies to the appropriate place and continues on with the build. If you go back and look at the list of questions in the first paragraph, you’ll notice that this process addresses most of them. This is why NuGet has become so incredibly popular.

So how do you take advantage of this goodness? Well, the starting point is found in the Solution Explorer. If you right-click on a project, you can find a Manage NuGet Packages option. Or if you right-click on the solution, the context menu contains a Manage NuGet Packages for Solution option. In both cases, you are taking to the page found in Figure 18-5.

Snapshot of  Manage NuGet Packages window.

FIGURE 18-5

The starting point is to show all of the currently installed packages. They appear in the list on the left. If you select any one of them, the details about the package appear on the right. On the right side, you have the ability to uninstall a package by clicking on the Uninstall button. You can also update a package, presuming that the current version is different than the installed version. If you’re just interested in updating all of your packages, there is an Updates link at the top that changes the list of installed packages to a list of those packages that actually have updates available.

If you want to install a package, click on the Browse link at the top and enter the name of the package. Packages that match the entered name (it is a wildcard search) appear in the list on the left. As before, when you select a package on the left, the details for the package, including a list of versions you can install, appear on the right.

One of the nice functions of NuGet is that installing a package makes sure that the dependencies of the package have already been installed on your machine. And, if they are not already available, then the dependencies are installed along with the package. So one way or another, at the end of the process, the package has everything it needs to run successfully. For any of the packages that you select, the list of dependencies is visible on the right. Well, it’s visible if you scroll down. It’s at the bottom of the details for the selected package (see Figure 18-6).

Snapshot of Json.NET package.

FIGURE 18-6

At the beginning of this process, there were two entry points into the NuGet page: from the project context menu and from the solution context menu. The difference is a behavior when you select a package to install or update. Figure 18-7 shows the left side of the NuGet page when you have chosen the Manage NuGet Packages for Solution option. At the top of the page, there is a list of the projects that are part of the solution. You can select one or more projects into which you want to install the package. Beyond that, the installation, uninstallation or update flow is the same.

Snapshot of left side of the NuGet page.

FIGURE 18-7

If a fancy graphical interface is not your style, then there is a command-line interface that can be used to manage NuGet packages. Use the Tools ➪ NuGet Package Manager ➪ Package Manager Console option to launch the command-line window. An example of the window is shown in Figure 18-8.

Snapshot of Package Manager Console window.

FIGURE 18-8

To install a package, choose the project into which you want to target from the dropdown at the top. Then use the Install-Package command, as illustrated in Figure 18-8 to install the package. There are other commands available, such as Uninstall-Package, as well as various command-line options to perform updates to packages. Use the Get-Help command to see the available options for a command (for example, Get-Help Install-Package shows all of the options available for Get-Help).

There is one final hidden gem about Visual Studio 2017 and NuGet. Visual Studio 2017 provides the ability to have Intellisense recommend the installation of a package based on the syntax of the code you’re typing. This option is turned off by default (it does take up a decent amount of memory), so to enable it go to Tools ➪ Options to get to the Options Dialog. Then navigate to Text Editor ➪ C# ➪ Advanced (shown in Figure 18-9). There are two choices that control this feature. Make sure that Suggest usings for types in reference assemblies and Suggest usings for types in NuGet packages are checked.

Snapshot of Options Dialog.

FIGURE 18-9

Once these options have been selected, then a couple of new options are available in certain Quick Action context menus. Consider Figure 18-10, which illustrates the context menu when you enter JObject, the name of a class that is a part of the common library JSON.Net.

Snapshot of context menu when entering JObject.

FIGURE 18-10

As the last option in the menu, you will notice an option to Install package ‘Newtonsoft.Json’. This option includes two additional choices. The first, when selected, will automatically install the most recent stable version of JSON.NET. The second choice opens the NuGet Package Manager, giving you the flexibility to install the version of your choice.

BOWER PACKAGE MANAGER

Since the previous section talked about a different package manager (NuGet), a reasonable question could be why we need another. Well, the reason has got to do with the target for NuGet, which is packages that are used with .NET. What NuGet doesn’t deliver is packages that contain only web content, which includes HTML, CSS and JavaScript files. That is the space into which Bower fits.

Functionally, Bower takes many of the same steps that NuGet does. When you build your application, Bower checks to make sure that all of the web files that you need to have are downloaded onto your machine. It also manages the dependency graph to minimize the number of times the same file might be used within the different packages. For instance, if you have two packages that depend on jQuery, Bower ensures that it is only downloaded a single time.

There are two ways to specify the files that Bower needs to include in your project. One is to use a graphical user interface, and the other is to edit the bower.json file to manually indicate which packages you want to include.

The graphical interface is quite similar to NuGet. To get started, right-click on a project in Solution Explorer and select Manage Bower Packages. A screen similar to Figure 18-11 appears.

Snapshot of Bower:ASPNETCore App window.

FIGURE 18-11

Initially (but not shown in Figure 18-11), the Installed tab is displayed and the dialog shows a list of the packages that have already been registered with Bower on the left side. If you have used one of the ASP.NET Core templates, this includes Bootstrap, jQuery, and jQuery Validation. If you select one of the packages, details about that package appear on the right side of the page. There are also buttons that enable you to uninstall or upgrade the package, presuming that a more recent version is available. A dropdown list shows all of the available versions.

To add a package to your project, click on the Browse header and enter the name (or part of the name) of the package you’re interested in. A list of the matching packages appears. In Figure 18-11, a search for moment has been performed and the base moment package has been selected for installation. On the right side, details about moment are visible, including a dropdown showing the versions and a button that will install the package. There is also a checkbox that, when selected, will update the bower.json file. More on this file momentarily (pun intended).

You can also update packages that have already been installed in your project to more current versions. To do this, click on the Update Available header. Now the left side contains those installed packages where updates are available and, when you select a package, the details and the button that can be used to update the package appear.

Also, next to the search text box is a checkbox used to indicate that you are interested in seeing pre-release versions as well as stable or released versions. By default, only stable versions are displayed. However, if this checkbox is checked, then the list of available versions includes both beta and alpha version of the package.

Besides the graphical interface, there is also a manual way to indicate the packages that you would like to include with your project. This involves directly editing the bower.json file. The file contains a list of the dependencies and, as was described earlier, can be updated through the graphic Bower Package Manager. Following are the contents of the bower.json file as included in the ASP.NET Core templates.

{
  "name": "asp.net",
  "private": true,
  "dependencies": {
    "bootstrap": "3.3.7",
    "jquery": "2.2.0",
    "jquery-validation": "1.14.0",
    "jquery-validation-unobtrusive": "3.2.6"
  }
}

As you can see, this is a relatively straightforward JSON file that contains a list of the dependent packages and the version that the project requires. Editing it is pretty simple. To add moment, for example, just add the following line to the list of dependencies.

 "moment": "2.18.1" 

If that were all Visual Studio 2017 offered, that would be okay. However, the bower.json file also includes Intellisense support (see Figure 18-12).

Illustration of bower.json file.

FIGURE 18-12

When you start typing the name of the package, a list of the packages that match what you type appears. Once you have selected a package, the second component shows a list of the matching versions.

One thing to notice in Figure 18-12 is that the contents of the value after the package name is not just limited to a specific version. If the version number is prefixed with a caret (^), then any version that matches the major version is considered acceptable. For example, if the value is “^2.18.2”, then the latest version with a major version of 2 will be downloaded. If the version number is prefixed with a tilde (~), then the most recent minor version will be downloaded. For example, with a value of “~2.18.2”, the latest version that starts with 2.18 will be downloaded.

SUMMARY

ASP.NET Core provides a platform that allows you to develop web applications that can be deployed onto a wider variety of machines than ever before. To help with that deployment, the ASP.NET Core project templates provide built-in support for some of the more commonly used web development tools. Visual Studio 2017 has integrated a number of features to provide an interesting and productive step forward for those people who are currently taking advantage of the ecosystem that has built up around the modern web.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.15.94