The History of ASP.NET – Part III (Covers ASP.NET Core)

Posted by: Daniel Jimenez Garcia , on 5/3/2019, in Category ASP.NET
Views: 35205
Abstract: In the 3rd and final part of the ASP.NET Evolution series, we will see ASP.NET transition to ASP.NET Core - an open source, cross platform - one that fully embraces the nature of the web.

Editorial Note: The vNext and Looking Ahead sections of this tutorial are being updated to reflect the latest changes.

The first version of ASP.NET was released 17 years ago in early 2002 as part of the version 1.0 of the .NET Framework. It was initially designed to provide a better web platform than classic ASP and ActiveX, one that could feel familiar to existing Windows developers.

I started a three part series to cover the history of ASP.NET from its launch to the latest ASP.NET Core releases.

Make sure to read the following articles (Part 1 and 2):

The History of ASP.NET – Part I

The History of ASP.NET – Part II

Through these tutorials, we have seen ASP.NET evolve and react to the major shifts happening in the web throughout these years .

In this last article of the series, we will take a look at the last step in its evolution - One that finished the transition from a closed platform that tried to hide and abstract the web, into an open source, cross platform one that fully embraces the nature of the web.

 

ASP.NET Core present (2014-today)

It seemed like the ASP.NET team had finally achieved its long-term vision with the One ASP.NET idea and its different frameworks. But this was far from truth. The team was busy taking a much deeper look at the framework and even at its .NET fundamental roots. They even decided to code name ASP.NET vNext internally instead of its (then) public name ASP.NET 5.

This took many by surprise, but the roots could be seen in the Project Katana, Microsoft’s OWIN (Open Web Interface for .NET) implementation for .NET. OWIN and Katana were Microsoft’s initial attempt at modernizing ASP.NET by taking inspiration from the likes of Ruby and Node. It tried to provide a lightweight web platform (no System.Web) built on best practices learned from other frameworks (request pipeline composed of middleware functions) that could be hosted on any server.

Project Katana was released in 2013 with two of the existing ASP.NET libraries, Web API and SignalR becoming compatible with it. For example, it was possible to host Web API as a console app thanks to its OWIN compatibility.

As of today, OWIN has been superseded by ASP.NET Core, since it achieves the same goals and more.

Looking back, it’s easy to see the ASP.NET team testing the direction and gaining knowledge before embarking on the ASP.NET Core journey.

Early development stages, ASP.NET vNext

As early as May 2014, David Fowler announced vNext was in the works:

For the past few months I've been working on what we're now calling ASP.NET vNext […] We took a look at some of the common problems that exist in our ecosystem today, and took best practices learned around .NET, ASP.NET and web development over the years and combined them to come up with the following requirements.

And right at the end of his blog post one could read the following:

Bonus: We are working with the Mono team to make it work with *nix, osx

Although Mono had been around for quite some time (version 1.0 released in 2004), this was the first time Microsoft would build a cross-platform .NET product! In a follow-up blogpost he shared preliminary details of the new architecture, including its new runtime (back in those days known as the KRuntime), new HTTP abstractions, simplified hosting and the plans to unify MVC/Web API.

Around the same time Scott Hanselman also posted on his blog about vNext. He showed the new runtime in action, highlighted how NuGet was used to manage all the dependencies and gave us a glimpse of the new project.json project file.

{
  "webroot": "wwwroot",
  "version": "1.0.0-*",
  "exclude": [
    "wwwroot"
  ],
  "packExclude": [
    "**.kproj",
    "**.user",
    "**.vspscc"
  ],
  "dependencies": {
    "Microsoft.AspNet.Mvc ": "1.0.0-beta1",
    "Microsoft.AspNet.Hosting ": "1.0.0-beta1",
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta1"
  },
  "frameworks": {
    "aspnet50": { },
    "aspnetcore50": { }
  },
  "commands":{
    "web": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:50
  }
}

While the change to project.json was sadly dropped in Core 1.1.1, in favor of a simplified .csproj (to remain compatible with existing tooling), it’s another great example of the bold approach taken by the team.

Scott Hanselman also gave an important hint of the open source mentality that was driving the team:

There’s some really cool stuff going on on the ASP.NET and Web Tools team. The team has been pushing open stuff at Microsoft for a few years now and we've joined forces with the amazing innovators from the .NET core team and beyond!

This had been a very slow revolution that took them years to accomplish. Remember when we looked back at Microsoft AJAX and its MS-PL license? It’s great to see that from those humble beginnings, the team managed to fully adopt open source. With vNext they were planning to do a complete rewrite of ASP.NET with a new CLR while doing development in the open, using GitHub for code and issue tracking, community standups and which would end up releasing under the Apache license.

I recommend reading Scott Hunter’s excellent entry Starting the .NET open source revolution.

As the work on vNext continued, the team was keen on sharing information and receiving feedback. For example, Daniel Roth wrote for the MSDN magazine in Oct 2014 an entry about the recently released ASP.NET 5 preview. This would reinstate the goals of a cross-platform framework, flexible hosting, unified MVC/Web API models, built-in dependency injection, a new request pipeline based on the middleware concept and with NuGet packages as the unit of dependency.

ASP.NET shipped as part of the Microsoft .NET Framework 1.0, released in 2002 along with Visual Studio 2002. It was an evolution of Active Server Pages (ASP) that brought object-oriented design, the .NET Base Class Libraries (BCLs), better performance and much more. ASP.NET was designed to make it easy for developers used to writing desktop applications to build Web applications with ASP.NET Web Forms. As the Web evolved, new frameworks were added to ASP.NET: MVC in 2008, Web Pages in 2010, and Web API and SignalR in 2012. Each of these new frameworks built on top of the base from ASP.NET 1.0.

With ASP.NET 5, ASP.NET is being reimagined just like ASP was reimagined to ASP.NET in 2002.

After years of focus on GUI-based tools for Visual Studio, it was refreshing to see a new take on command line tools as part of the new framework. The initial previews used the so called KRuntime, with 3 different CLI tools:

  • kvm – used to install and switch between versions of the runtime
  • kpm – used to restore project dependencies and package (or build) a project into a self-contained image
  • k – used to run commands defined in the project.json file, starting the application

One would kvm list existing versions of the runtime, kpm restore && kpm pack your project and finally k web to run it on localhost. If these commands sound alien to you, it is because they went through a couple of renames. The KRuntime became the DNX runtime and the commands became dnvm, dnu and dnx instead of kvm, kpm and k. They would change once more with ASP.NET Core 1.0 as part of the unified dotnet CLI, becoming subcommands like dotnet list, dotnet restore, dotnet publish, dotnet run, etc.

ASP.NET vNext vs Node.js

It is amusing to see how similar vNext appears to Node.js and this isn’t a coincidence since Node.js is admittedly one of its influences, alongside Ruby, Go, the learnings from Project Katana and others:

aspnetcore-vs-nodejs

Figure 1: ASP.NET vNext vs Node.js

The development process would continue, with up to 8 beta public releases before the first RC (Release Candidate) was released in November 2015. There would still be a second RC release in May 2016 when ASP.NET 5 was officially renamed as ASP.NET Core (ASP.NET vNext had always been an internal name) alongside a renamed .NET Core framework. Before RC2 was released, Scott Hanselman had already announced the rename and explained the reasons for it (since it caused some pain for early RC1 adopters):

Why 1.0? Because these are new. The whole .NET Core concept is new. The .NET Core 1.0 CLI is very new. Not only that, but .NET Core isn't as complete as the full .NET Framework 4.6. We're still exploring server-side graphics libraries. We're still exploring gaps between ASP.NET 4.6 and ASP.NET Core 1.0.

Armed with a new name that conveyed better the difference between ASP.NET Core and the existing ASP.NET, the team was ready for the initial launch.

ASP.NET Core launch

ASP.NET Core 1.0 was finally released in late June 2016. It took more than two years of development, but the result was certainly promising. As Microsoft would put it in its announcement:

We challenged everything instead of delivering an incremental update so you can have an extremely modular, fast and lightweight platform perfect for the new era of software development where monolithic applications are replaced by small, autonomous services that can be deployed individually. All of that while keeping and extending what .NET is best for: developer productivity, and modern languages and libraries. […] The end result is an ASP.NET that you’ll feel very familiar with, and which is also now even more tuned for modern web development.

Creating a web application in ASP.NET Core felt very similar to creating an MVC/Web API application. A controller wasn’t much different from the earlier model, in fact this could very well be ASP.NET MVC code:

public class HelloWorldController: Controller
{
    public IActionResult Index()
    {
        return View();      
    }
        
    [HttpPost]
    public IActionResult Index(String name)
    {  
        return View(name);
    }  
}

Its corresponding Index.cshtml view using Razor also appeared familiar, even though it hinted at one of the main changes in Views, the Tag Helpers:

@model String

@if (Model != null) {
    <p>Hello @Model</p>
}
<form asp-action="Index">
    <p>
        <label for="name">Name:</label>
        <input id="name" name="name" type="text">        
    </p>
    <input type="submit" value="Say Hi" />
</form>

However once one started scratching the surface, the differences started becoming evident.

The first one is the new request pipeline based on middleware functions. Common functionality like Authentication is implemented as a middleware, and developers can easily create and register their own middleware. This way a pipeline gets defined, in which a request flows through the different middleware until it reaches the routing middleware that delegates to the controller action. And that’s assuming a traditional MVC model is being used, the framework is flexible enough. Replacing Routing with a simple request handler written by you, is very straightforward.

aspnetcore-request-pipeline

Figure 2: Unified request pipeline in ASP.NET Core

Looking past the middleware concept, we also had a dependency injection framework built-in, with the dependency inversion pattern applied throughout the framework. There was also a completely different project startup and setup that reflected the new lightweight hosting approach and the middleware-based pipeline.

Some of the most immediately obvious improvements were the additions made to Razor for building cleaner views. I am referring to Tag Helpers and View Components which replace the old MVC HtmlHelpers and Partial Views. Check out one of my earlier articles to see how these could be used to create cleaner views.

When we got our hands on the 1.0 version, the ASP.NET team was busy working on the following releases. In November 2016, version 1.1.0 was released with several improvements and refinements like the usage of middleware as filters or the possibility to render any View Component with a Tag Helper. The latter would make the usage of View Components very similar to the usage of components in any JavaScript SPA framework. That is, to render a View Component called LatestArticles it was now possible to simply write <vc:latest-articles></vc:latest-articles> instead of @await Component.InvokeAsync(“LatestArticles”).

There would be two more minor releases, 1.1.1 and 1.1.2 before the next major release was publicly announced.

ASP.NET Core 2.0 and the future roadmap

After two previews, ASP.NET Core 2.0 was finally released during August 2017.

One of its biggest features was the inclusion of Razor Pages, which in a way brings back the Page Controller pattern we discussed during the design of Web Forms in 2003!

However, this time there is no forms abstraction, and instead we are fully in control of the HTTP requests and the generated HTML. Our HelloWorld example can be implemented as a new HelloWorld.cshtml page:

@page
@model HelloWorldModel

@if (Name != null) {
    <p>Hello @Name</p>
}
<form method="post">
    <p>
        <label asp-for="Name "></label>
        <input class="form-control" asp-for="Name" />        
    </p>
    <input type="submit" value="Say Hi" />
</form>

Alongside its code-behind file (yes, we got back the code-behind. Isn’t it fun how it all comes around?) implementing a Page Model:

public class HelloWorldModel: PageModel
{
    [BindProperty]
    public String Name { get; set; }

    public IActionResult OnPost()
    {
        Return Page();
    }
}

This added to the framework the possibility to use the MVVM (Model View View-Model) pattern that developers can mix and match with the traditional MVC approach according to their needs.

Another important addition in ASP.NET Core 2.0 was the introduction of IHostingService. This brings a very convenient and straightforward way to run background processes alongside your web application. This was great for scenarios that don’t require complex distributed architectures. You can read more about these and other features in one of our earlier articles on ASP.NET Core 2.0.

Version 2.1.0 was released in May 2018 and amongst many features and improvements, it finally brought the rewritten SignalR framework into ASP.NET Core. This is a simpler, more performant and lightweight version of SignalR, designed to scale and take advantage of .NET Core.

The broader .NET Core received global tools as a means to install global command-line tools, similar to globally installed NPM packages. It is still early days to see if this will cause a boom of tools written in .NET like it happened in Node.js, but the curated list by Nate McMaster is quickly getting longer.

With SignalR and Razor Pages, the original set of libraries under One ASP.NET had finally been ported to .NET Core! (Assuming Razor Pages as the counterpart for both Web Forms and Web Pages)

Looking ahead, we can see two exciting features in the imminent release of .NET Core 3.0:

  • Support for Windows applications will finally be added, allowing WinForms, WPF and UWP applications to be supported in Core 3.0
  • (Outdated section) The no longer experimental Blazor framework (now in preview) will partially ship with .NET Core 3.0. This is explained by the fact that the server-side model of Blazor will be extracted and renamed as Server-side Blazor (previously called Razor Components). The client-side model based on web assembly, which can run .NET in the browser will become the sole model of Blazor and will remain an experimental release not ready for production. Check our article about Blazor to understand more about both modes Also get the latest updates from the official Blazor website .

Let’s not forget all the performance improvements that have been made in .NET Core, and the introduction of constructs like Span<T> that have made ASP.NET Core 2.2 the 3rd fastest web server (in plain text responses) according to TechEmpower benchmarks. The team has promised an even better performance for its next release.

Seems like the future is bright for ASP.NET, even 17 years after its first release!

And funnily enough, with Razor Components being part of ASP.NET Core 3.0, we have gone a full circle again towards a page model encapsulating template and logic, able to react to UX events. Although this time it is actually running in the same process, except a small client in the browser, rendering the DOM updates pushed through a SignalR connection.

Conclusion

17 years is a long time. During these years we have seen ASP.NET rise after its initial launch, struggle with the pace of changes in the web, correct its course and finally re-invent itself as one of the fastest servers available by running on Linux.

Along the way, a closed-source Microsoft product with an ecosystem that suffered from the “not invented here” syndrome has turned into an open source community, in a huge way, thanks to the efforts of the ASP.NET team.

I hope you have enjoyed this nostalgic trip back in time. I can only wonder what the future might bring!

This article was technically reviewed by Damir Arh.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Daniel Jimenez Garciais a passionate software developer with 10+ years of experience who likes to share his knowledge and has been publishing articles since 2016. He started his career as a Microsoft developer focused mainly on .NET, C# and SQL Server. In the latter half of his career he worked on a broader set of technologies and platforms with a special interest for .NET Core, Node.js, Vue, Python, Docker and Kubernetes. You can check out his repos.


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!