It’s been a long journey, but ASP.NET Core and .NET Core were v1.0 releases in June of 2016. A lot’s changed since I wrote my first articles for ASP.NET vNext in CODE Magazine (Jan/Feb 2015)..
Version 1.0 of .NET Core and ASP.NET Core will very much be a 1.0 product. The platform will grow and improve from there.
ASP.NET and .NET Core Today
After a lot of anticipation and delays, ASP.NET Core and .NET Core 1.0 have finally been released. The last couple of years have been tough if you’ve been keeping up with Microsoft’s ever-changing architectures for the new .NET platform. The .NET Core platform has gone through three major platform updates since this journey to reboot .NET started nearly three years ago, but now it finally seems that all of this churn is coming together in a much clearer vision of where .NET is headed. Even so, not all of this unification and integration has come to fruition with the RTM release because more post-RTM changes have already been announced.
This initial release is about drawing a line in the sand and having a stable base on top of which, additional frameworks, components and updated features can be built. It's also a stake in the ground to let people start using an officially released version of these new tools. Microsoft is quite adamant in saying that although a lot more changes are coming in the future both for .NET Core and ASP.NET Core, these changes are not going to be as drastic as some of the changes that we can see in the latest release. Instead, future changes are supposed to light up new functionality that won't break backward compatibility.
Version 1.0 was released with a solid tooling infrastructure, a solid but "snapshot in time" version of the .NET Core framework and a fully functional ASP.NET application layer. Of these major components, the one most in flux is .NET Core, which is going to gain additional features to bring it closer to the full .NET Framework. The v1.0 release is meant to bring a production-ready and fully supported release of the .NET Core and ASP.NET Core systems so that early adopters have a solid, base-production framework that’s officially supported by Microsoft to deploy on.
With .NET Core and ASP.NET Core, Microsoft is on a mission to build a unified .NET base library that provides a common .NET baseline that all platforms running .NET can take advantage of.
Microsoft proposes to create a new .NET Standard, which defines a common base layer that a platform should support. They plan to implement this new .NET Standard across the runtimes that Microsoft itself publishes. It's very likely that ultimately, .NET Core, which is an implementation of .NET Standard, will figure heavily in this vision, with .NET Core providing a single implementation that can run on many platforms. We're already seeing that with support for .NET Core on Windows, Mac, and Linux for the server version. But there are more OSs to worry about—Xamarin’s mobile platforms running Mono, UWP Windows application, game development platforms and the desktop OS implementations that are currently served by Mono. As of the RTM release, the landscape is starting to come together with the common infrastructure layer shown in Figure 1.
The .NET Common Infrastructure
On the bottom of the stack, you have the common infrastructure and tools that provide the base rock of the platform: The Roslyn Compiler platform, C#, VB.NET, F#, and the runtime loaders and the new dotnet.exe-based command line tools. The important thing about this base is that it provides a single set of tools to get started with .NET. In this scenario, .NET is installed from a single .NET SDK.(s) using the correct runtimes. You don’t need Visual Studio or to install a host of other .NET SDKs—all that’s needed is the single .NET SDK that gets you everything you need to do it all. This common set of tools can be used to build, package, and deploy applications, as I’ll show later in this article.
This may not seem very significant at first glance, but if you compare this to the process of getting started with .NET today, it’s a big step forward. Rather than installing the huge monster that is Visual Studio and that gives you everything under the sun, or installing a host of disparate SDKs and support tools, a single reasonably sized SDK install gets you everything you need to build and run any kind of .NET application. You can get started with .NET after a few minutes of download and a short install.
To be clear: We’re not there yet, as support for .NET Standard currently is limited to .NET Core applications at the moment, but if you’re building apps with ASP.NET Core or .NET Core, you can see and try out how this process works and I’ll show you how in this article.
The dotnet command line tools combine compiler, runtime loaders, package management, and deployment into a single, easy-to-use environment.
An important component of the new .NET infrastructure is the dotnet command line interface (CLI) that lets you do all build- and run-related tasks via command line tooling. When you install the SDK (see the Getting .NET sidebar), the dotnet command line tool is referenced in your path. You can say dotnet new to scaffold a simple HelloWorld console project that you can modify and edit in a plain text editor. You can then do dotnet restore to restore missing NuGet packages, including runtimes, followed by dotnet run to execute the application. Both dotnet build and dotnet pack can build and package your application and component packages, and dotnet publish can deploy an application to a server or other packing location. This simple command line front-end interface wraps up a ton of disparate tooling under a single installable package, which makes it much easier and quicker to get started with .NET. And to top it off, these tools work the same on all of the operating systems that .NET now supports: Windows, Mac, and Linux. This tooling significantly lowers the barrier of entry to starting with .NET regardless of the platform you’re using.
Base Class Libraries. There are tons of libraries, all similar and providing common .NET functionality, but all with different levels of feature support. For developers and especially component developers, it hasn’t been a major headache to support so many variations of .NET.
Today, .NET Core is the key for Microsoft’s journey to moving to a single .NET Standard Library, which is meant to provide a core base line for the .NET Framework across all platforms, which is shown in Figure 2. We’re not yet there obviously, but a .NET Core stack with ASP.NET gives you a good glimpse of what development will look like for all platforms using .NET Standard. There’s a lot of discussion around this today and even though .NET Core is currently in v1.0, there’s already talk that .NET Core will continue to gain a lot more full framework .NET features in the future.
The .NET Standard Library will eventually replace the multitude of .NET runtime implementations with a common baseline implementation.
Application Libraries
The push for a standard .NET library makes it much clearer where the boundaries are between the base library and the application layer. Because the standard library has to be able to run cross-platform, a lot of feature functionality, like OS-specific library features, have to move higher up the stack into the application frameworks. To be clear, what the .NET Standard Library addresses is akin to what was called the BCL (Base Class Library: the stuff in mscorlib.dll) of old. Additional services that traditionally were services of the FCL (Function Class Library) have to move to the specific framework/application layer.
For the full .NET Framework, this includes common application frameworks that we use to build desktop and server applications. WPF, WinForms, Console apps, Services, and ASP.NET apps of all stripes. Note that the full framework doesn’t go away. It will continue to be delivered and improved on with its Windows-centric focus and support of all the Windows-specific and rich application features that you’re using today. This means that you’re not required to move to .NET Core or ASP.NET Core; your existing applications and new applications built with ASP.NET MVC 5 using the System.Web-based ASP.NET stack will continue to work and are still viable for new projects going forward.
It’s clear that .NET Core is where most of the excitement is because that’s where most of the new features of .NET are being tried out and implemented from the Microsoft side. ASP.NET Core is the application framework that’s getting a lot of attention because it’s one of the first big frameworks built on top of the .NET Core framework using the current .NET Standard Library implementation.
Although Figure 2 doesn’t describe this use case well, ASP.NET Core can also use the full .NET Framework to run ASP.NET Core applications. But even if it’s possible to do, I think that this is not the optimal use case for ASP.NET Core. If you’re considering ASP.NET Core, most likely you’re considering it for its new features, like reduced footprint, high performance infrastructure, and the cross-platform capabilities that aren’t directly available to full framework ASP.NET Core applications. To take full advantage of all that ASP.NET Core has to offer, you really have to use .NET Core.
Finally, on the right, we have Xamarin and the various client and mobile platforms which, to date, are based on Mono. Mono is a port of the full .NET Framework that runs on Mac, Linux, Android, and iOS. Because Microsoft has acquired Xamarin recently, Mono and .NET Core are starting to converge and it’s expected that eventually Xamarin -based tools will use .NET Standard as well. The idea is to bring all platforms together under a single standard library so you can get the consistency of a single implementation.
The take-away from all of this is that the .NET platform on various devices and operating systems is becoming much more unified. As we now know, this hasn’t all happened with the .NET Core and ASP.NET 1.0 releases this summer. There will be additional , hopefully, incremental and non-breaking improvements that bring .NET Core closer to what’s in the current full framework BCL. What all this means is that you can build on .NET Core today, and expect more features to light up in the future, so things will get easier as time goes on. Whether you want to be an early adopter with the less featured framework now, or jump in later is going to be a decision that you have to make on your own.
Now that you have an idea of the overall architecture that you end up using with ASP.NET Core, let’s jump in and do something practical.
Getting Started with .NET Core
To demonstrate the new command-line tooling, let’s quickly demonstrate how to create a new .NET application using the command line tooling. I’ll use Windows here, but note that you can also do the same thing on a Mac or Linux computer if the .NET SDK is installed. The steps are the same, so you can follow along on a Mac or Linux.
Start by downloading the .NET SDK from. Click on the .NET Core link and follow the installation instructions for your platform. To create a new project, you can follow the directions from that page. Figure 3 shows the command line output as you create the new project.
The steps are:
- Create a new folder.
- Change path to the folder.
- Rundotnetnew to create a new project.
- Rundotnetrestore to bring down NuGet packages required.
- Rundotnetrun to run the application.
As you can see in Figure 3, the output of this console application is dumped to the console. You’ve just created and run a .NET application in three simple commands.
You can create and run a boilerplate .NET application with three simple commands from the command line.
You can now open the program.cs file that was generated and change the code. For example, change the Console.WriteLine() to add a date and time:
Console.WriteLine("Hello World! Time is: " + DateTime.Now);
Back at the command line, now run dotnet run and you should see the updated message, including the time, displayed.
The cool thing about this isn’t so much that you can do this from the command line, but the fact that it’s very easy to get started. Download a relatively small SDK, install it, scaffold a base project, and then use a text editor to make a change to your code and run.
That isn’t to say that you’re going to have to build your application from the command line now (see the Command Line versus Visual Studio sidebar). In fact, if you install the Visual Studio tooling for ASP.NET Core, you get Visual Studio integration like you’d.
What about ASP.NET?
Okay, so far, I’ve talked about a lot of general .NET stuff, in Listing 1.
You’ll also need to make a small change in project.json to add references for a couple of dependencies that pull in the Kestrel Web server and HTTP extensions:
"dependencies": { "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", },
Now, go back to the command line and run the application again and you’ll get a prompt that states that the Web server has been started on port 5000. Navigate to and…voila: HelloWorld from ASP.NET Core. You’ll get a plain text string:
Hello World. The Time is: 6/3/2016 2:32:20 PM.
ASP.NET Core applications are self-contained Console applications that self-host the Kestrel Web server.
Middleware
To make ASP.NET do something useful, you need to use middleware. Middleware is essentially what we thought of as HttpHandlers and HttpModules in older versions of ASP.NET; it’s the stuff that makes things happen in an ASP.NET Core Web application.’s fired when nothing else has handled the request. In the example above, there’s nothing else handling requests, so the App.Run() handler is fired and you see the HelloWorld message.
If App.Run() is like an HTTP handler, App.Use() is like an HttpModule. App.Use() handlers can be chained together and are fired in the order that they’re assigned. Unlike HttpModules, they can handlerun it with dotnet run, you should now get:
Pre Processing...Hello World. The Time is: 6/3/2016 3:10:19 PM Post. Again, if you think of the analogy with older ASP.NET versions, you can think of it as pre- and post-request handler processing. All of the pre-handlers fire until the pipeline has no more middleware or an operation doesn’t call next() (like our App.Run() handler), and then it reverses and walks the chain the other way. Note that middleware can handle both the inbound and outbound processing with a single middleware implementation. It’s a simple and elegant, but very low-level concept.
Hooking up ASP.NET MVC
App.Use() and App.Run() are very low-level, to application is fairly similar to the way you built older ASP.NET MVC applications.
To demonstrate, let’s add ASP.NET MVC to the startup sample and create a simple API endpoint that returns some JSON data to show that it works.
The first step is to get the right packages loaded. Add the following to your dependencies in project.json:
"Microsoft.AspNetCore.Mvc": "1.0.0",
Next, add the following configuration code to the Startup class:ervers() initializes dependency injection services, typically with configuration settings that are set up so that dependency injection creates types with the right configuration settings when injected. Configure() then adjusts the behavior of the middleware, which is usually.
All that’s left now is to create a controller. I’m going to start with an API request and I’ll create a good old HelloWorld API request. To do this, create a class like this in the same program.cs file you used earlier:
public class HelloWorldController { [HttpGet("api/helloworld")] public object HelloWorld() { return new { message = "Hello World", time = DateTime.Now }; } }
Now go back to the command line and again do dotnet run. Then navigate to. You should now get:
{ message: "Hello World", time: "2016-06-03T15:39:18.339626-07:00" }
Note that the controller implementation.
The MVC engine in ASP.NET Core combines MVC and WebAPI in a single framework.
Adding MVC and Razor Views
Finally, let’s add another method to the controller and render a Helloworld View page. To do this, you need to make a configuration change. Set the UseContentRoot() in the Main() startup to provide a root path for the application:
public static void Main(string[] args) { var host = new WebHostBuilder() .UseContentRoot( Directory.GetCurrentDirectory()) .UseKestrel() .UseStartup<Startup>() .Build(); host.Run(); }
Without this configuration step, MVC can’t find Views referenced from your Controller code.
Now you can add a Controller method to the existing Helloworld controller. Note that ASP.NET Core’s MVC version supports both API and MVC endpoints in the same controller, so you didn’t inherit from Controller and was a POCO object. For running the above example, you’re relying on some controller features like ViewBag and the View() method, so you have to inherit from Controller to get access to these features. Change the Controller class definition to:
public class HelloworldController : Controller
Now, all you need is a View. ASP.NET Core MVC uses standard View discovery logic by default, so it’s looking in the /Views/Helloworld folder for a HelloworldMvc.cshtml view. Instead, create a helloworld.cshtml view, which is reflected by explicitly specifying the requested view in the View("helloworld") call.
The view is ultra simple and just used to demonstrate that it works:
Message: @ViewBag.Message < hr /> Time: @ViewBag.Time
This simply echoes out the Viewbag values you.
When you run the application now again with dotnet run you should see:
Message: Hello world! --- Time: 6/3/2016 9:29:12 PM
At this point, you started with a plain Console application, then added a low-level ASP.NET Core handler implementation, followed by an MVC API implementation, and finally an MVC View-based implementation. All of the code required to do this is in a single small code file of about 60 lines of code, as shown in Listing 2 (also see the Samples on GitHub sidebar).
Where’s IIS?
You may have noticed that I just ran a console application on Windows. There’s no IIS or other external Web server hosting the application. What’s happening is that ASP.NET Core uses a self-hosted Web Server (Kestrel, which is ASP.NET’s high-performance built-in Web Server) in a console application. The application is self-contained, running with its own private copy of .NET and its own Web server, which makes the application very portable. It’s portable in terms of deployment, but also portable in terms of platform; you can host this application on multiple operating systems and, assuming that, it’s recommended to, which can ensure that your application always stays running. If your application crashes, it’s automatically restarted, much in the same way that the Windows Activation Service (WAS) does today with IIS Application Pools. Figure 4 shows the interaction between IIS and your ASP.NET Core application.
There’s a native AspNetCoreModule that’s installed in IIS and handles ASP.NET Core routing and process management. This native module is lightweight and still requires an Application Pool but no .NET runtime, because IIS doesn’t do any direct request processing, but rather acts as a proxy to forward requests to your application.
Another benefit with this set up is that you can more easily set up load balancing and you can have a single server that requires an SSL certificate while the backplane runs over plain HTTP. You can also hide your application Web server from the Internet because only the IIS server needs to be publicly exposed.
When running ASP.NET Core on Windows, IIS is relegated to the job of reverse proxying and process management.
Running on a Mac
So far, I’ve run this little walk-through exclusively on the Windows computer, but I can take this entire application and now move it over and run it on the Mac without any changes to the code!
To make this happen, I’m pushing the project to source control on GitHub at.
The first thing that has to happen on the Mac side is to make sure that the .NET SDK is installed. If you haven’t installed it yet, you can find it at. on Linux, for that matter.
Once the SDK is installed, you can clone the repository from GitHub into any folder on your Mac or Linux computer. Once you’ve,, and to see the API, MVC, and raw App.Run() endpoints.
Although it’s not super practical or even realistic to have applications that run on multiple platforms, it’s pretty cool to see this work without any special effort or any code or configuration changes. You’re no longer limited to just running on Windows, which is exciting, as it opens many new opportunities for .NET code.
Granted, the examples are just about the most basic thing you can build, so it’s not too surprising that the code works across platforms. But I’ve also taken a few more involved data-centric applications and moved them over to the Mac. I was surprised to find them working just v1.0 release, the platform has finally found its stride in delivering on the promise of providing a more unified, more lightweight, and truly cross-platform .NET Framework.
Without a doubt, the new .NET Core platform will grow and continue to get richer. Version 1.0 is very much a 1.0 product with all of the warts and missing features that you’d expect from a 1.0 product. But now, there’s at least a common vision of where .NET is headed going forward, which up until very recently, was sadly missing. There’ll be changes going forward, but those changes are going to be primarily enhancements to existing functionality and features, rather than the groundbreaking, change-everything upheavals that have occurred several times during this long pre-release cycle. It’s taken Microsoft some time to find the right direction, but personally, I prefer that this process takes time, rather than rushing and ending up with an incomplete or difficult-to-use framework. From what I see today in v1.0, Microsoft is on the right path with the direction of .NET. You can get done what needs to get done to build applications with the feature set available.
All that said, adoption of ASP.NET Core right at the v1.0 release is not a slam dunk. There are a lot of decisions to be made by developers like you and me to decide whether .NET Core and ASP.NET Core are the right choice for applications initially. There are still a lot of missing features in the framework, especially when it comes to support of third-party libraries. If you need a particular library that hasn’t been ported, it might be very difficult to work around that library. It’s going to take time to get parity in this space, especially given the recent announcements that the post RTM .NET Standard enhancements will bring more features back that will make porting full .NET Framework code easier. Nobody wants to do a difficult port now, if an easier port based on a richer feature set in a few months will be available to make the process much smoother.
In the end, it all depends on the type of application you’re building and what dependencies your application has. For example, if you plan to host your application on Linux and you’re building small micro services that have small footprint and basic integration needs, ASP.NET Core is going to be a great choice. If you’re building a Web application that relies on a ton of Windows platform features, such as COM Interop, Active Directory, WMI etc., or uses a specific library that hasn’t been ported to .NET Core yet, it might not be such a great idea to jump right away. Either way, it’s a good idea to review carefully what your application requirements are, and whether all of the external dependencies and integrations you need to make your application work are available in .NET Core and ASP.NET Core initially.
Summing up
I’ve tackled an overview of the .NET Core and ASP.NET Core platforms that should give you a good idea of how the pieces fit together. The new dotnet tooling and single-point SDK installation go a long way toward making .NET more accessible not only to .NET developers but also those who are going to try .NET for the first time. Already, .NET Core provides impressive cross-platform functionality and the feature set is reasonably complete, with more features that bring it closer to full framework BCL functionality coming soon. I didn’t spend a lot of time on ASP.NET Core, but it currently feels very stable and there are many new features that make building MVC and API applications easier. I’ll talk more about these aspects in my next article in CODE Magazine.
In this article, I’ve purposefully stuck to the low-level aspects of creating an application using. I wanted to use this lower-level approach because it demonstrates so well how an application is put together. I hope you found this as useful as I found it when I worked through my exploration of .NET Core and ASP.NET Core.
In the next article, I’ll pick up where I left off this time, by creating a more realistic sample application to demonstrate what you can expect when creating a more realistic ASP.NET Core application with data access and some non-Helloworld UI. Until then, give ASP.NET Core a try and see what you think.