The new version of ASP.NET is called ASP.NET 5 and it has the most significant architectural redesign of ASP.NET. This article will highlight the new features and concepts in ASP.NET.

What is ASP.NET 5?

ASP.NET 5 is a new open-source and cross-platform framework for building modern cloud-based web app. It has been built from the ground up to provide an optimized development framework for web apps that are either deployed to the cloud or in your local servers. Adding to that, it was redesigned to make ASP.NET leaner, modular (so you can just add features that your application requires), cross-platform (so you can easily develop and run your app on Windows, Mac or Linux which is pretty awesome) and cloud optimized (so you can deploy and debug apps over the cloud). Read more here.

What does that mean for us who are working on previous versions of ASP.NET?

If you are using the past versions of ASP.NET or if you are coming from a WebForms development background then you might find ASP.NET 5 completely new. It’s like the feeling of moving from classic ASP to ASP.NET world or perhaps the feeling of my dog looking into my screen monitor while I was programming:

Now let’s get Cracking!

Here are the lists of the core significant changes in ASP.NET 5:

Cross-Platform Runtime

For the first time in the history of ASP.NET, you can run ASP.NET 5 applications on OSX and Linux. Yes ASP.NET 5 apps can run on Windows, OSX, and Linux. This fact opens up ASP.NET to a whole new audience of developers and designers. ASP.NET 5 comes with two different flavors of runtime environments when running your app. This means that you can choose two runtime environments to give you greater flexibility when deploying your apps and these are:

  • ASP.NET Core 5.0 or .NET Core is a refactored version of .NET. It was redesigned to be modular which allows developers to plug components which are only required for your project, most features will be available as plugins via NuGet. One of the good things about being modular is the ability to upgrade features without impacting the other features that your application uses. Adding to that, .NET Core is a cross-platform runtime which enables you to deploy app in OSX or Linux operating systems. It also is a cloud optimized runtime enables you to deploy and debug app in the cloud. The .NET Core can be bin-deployed along with your app, allowing you to run ASP.NET apps on the same server that target multiple versions of .NET Core.

  • ASP.NET 5.0 or the new .NET Full Framework enables you to utilize all the .NET components that are available and supports backward compatibility. If you plan on migrating apps to run on .NET Core then you may need to do some modifications since the .NET Core API is currently limited compared to the full .NET Framework.

ASP.NET is Not All About using Visual Studio

That’s right!, enabling ASP.NET 5 to run on Windows, OSX, and Linux changes everything. For the first time, developers and designers can start building apps with ASP.NET 5 using their favorite development environments such as Sublime Text, WebStorm, etc. when working with ASP.NET. That’s pretty awesome!

New Project Solution Structure

If you create an empty ASP.NET 5 project in Visual Studio 2015 you will be surprised seeing this (unless if you haven’t done creating any project before using previous versions of ASP.NET):

Surprised? Yes the new project structure is totally different. The project now includes the following new files:

  • global.json - this is where you put solution-level settings, and allows you to do project-to-project references.
  • src folder - contains all projects that contain source code that make up your application.
  • wwwroot - is a folder in which all your static files will be placed. These are the assets that your ASP.NET app will serve directly to the client including HTML, CSS, Images and JavaScript files.
  • project.json – contains project settings. In ASP.NET 5 you manage dependencies by adding nuget packages using NuGet Package Manager (NPM) or the new project.json file. This file enables you to easily manage dependencies in your application because you can edit it using any text editors. It would be easier to work with this file because in Visual Studio 2015, Intellisense will assist you finding the available NuGet packages that you can add as dependencies.
  • startup.cs – this is where you put your startup and configuration code for your ASP.NET 5 app. To give you a quick view here’s what the startup.cs class would look like:
public class Startup{
      public void ConfigureServices(IServiceCollection services) {}
      public void Configure(IApplicationBuilder app) {}

The ConfigureServices method defines the services used by your application and the Configure method is used to define what middleware makes up your request pipeline, for example MVC.

  • References - By default it contains ASP.NET 5.0 and ASP.NET Core 5.0 references. These enables you to choose what .NET runtime you’ll be going to use in your project.

You can add dependencies for each runtime reference within your project.json file. To select which .NET runtime to use, just go to Project > Properties.

WebForms No More

Yes it’s a sad fact that WebForms is no longer part of ASP.NET 5. Though you can still continue to build Web Forms apps in Visual Studio 2015 by targeting the framework .NET 4.6. However, Web Forms apps cannot take advantage new features of ASP.NET 5.

I’ve spent years building WebForms applications from small to large enterprise app. I love Web Forms; in fact I still continue supporting the community that uses WebForms at various forums such as However, it’s time to move forward, learn the new stuff and it’s finally time for you to learn ASP.NET MVC. Like so many things in the past, times are changing and you either adapt or you become extinct.

Aside from WebForms, the .NET Core in general will not include Windows Forms, WCF, WPF, Silverlight etc.

What about VB.NET?

Initially VB.NET wasn’t part of ASP.NET 5 but due to strong demands of VB.NET Community, looks like Microsoft will consider and ASP.NET 5 will now have full support for VB.NET in both tooling and runtime - including cross-platform runtime support. For details see: Visual Basic: Back by Popular Demand

MVC 6 the Unified Framework

In previous versions of ASP.NET MVC, MVC controllers were different from Web API controllers. An MVC controller used the System.Web.MVC.Controller base class and a Web API controller used the System.Web.Http.ApiController base class. In MVC 6, there is only one Controller base class for both MVC and Web API controllers which is the Microsoft.AspNet.Mvc.Controller class.

ASP.NET 5 will see MVC, Web API and Web Pages combined into one framework called MVC 6.

The merge is also true for HTML helpers in both MVC and Web Pages which are implemented differently before. The Web Pages programming model isn't available yet for the current release so we can never really tell what will be the other features that they're going to merge, but we can assume that the traditional MVC model-binding will be available to it.

View Components

In previous versions of ASP.NET MVC, the Html.Action() helper is typically used to invoke a sub-controller. ASP.NET MVC 6 introduced the new View Component to replace widgets that uses Html.Action().

View Components supports fully async allowing you to make view component asynchronous. Here's a sample view component that returns person profiles based on some status:

using Microsoft.AspNet.Mvc;
using MVC6Demo.Models;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace MVC6Demo.ViewComponents
    public class PersonListViewComponent : ViewComponent
        public async Task<IViewComponentResult> InvokeAsync(string status) {
            string viewToUse = "Default";
            bool isFiltered = false;

            PersonModel model = new PersonModel();

            if (status.ToLower().Equals("registered")) { viewToUse = "Registered"; isFiltered = true; }
            var p = await GetPersonAsync(status, isFiltered);
            return View(viewToUse,p);
        private Task<IEnumerable<Person>> GetPersonAsync(string status, bool isFiltered) {
            return Task.FromResult(GetPerson(status,isFiltered));
        private IEnumerable<Person> GetPerson(string status, bool isFiltered) {
            PersonModel model = new PersonModel();

            if (isFiltered)
                return model.GetPersonsByStatus(status);
                return model.GetAll;


And here’s the view for the View Component:

@model IEnumerable<MVC6Demo.Models.Person>

<h3>Person List</h3>
    @foreach (var p in Model) {
        <li>@string.Format("{0} {1}",p.FirstName,p.LastName)</li>

And here’s how you call the View Components in the main view:

    @await Component.InvokeAsync("PersonList","Registered")

New Directives: @inject, @using, @inherits

ASP.NET MVC 6 has few new directives that we can use in our application. Here we’ll take a look at how to use @inject. The @inject directive allows you to inject some method calls from a class or service directly to your view. Here’s a simple class that exposes some async methods:

using System.Threading.Tasks;
using System.Linq;

namespace MVC6Demo.Models
    public class Stats
        private PersonModel _persons = new PersonModel();

        public async Task<int> GetPersonCount() {
            return await Task.FromResult(_persons.GetAll.Count());

        public async Task<int> GetRegisteredPersonCount() {
            return await Task.FromResult(_persons.GetAll.Where(o => o.Status.ToLower().Equals("registered")).Count());

        public async Task<int> GetUnRegisteredPersonCount() {
            return await Task.FromResult(_persons.GetAll.Where(o => o.Status.ToLower().Equals("")).Count());

Now we can call those methods in the view using @inject like:

@inject MVC6Demo.Models.Stats Stats

    ViewBag.Title = "Stats";

    <p>Registered: @await Stats.GetRegisteredPersonCount()</p>
    <p>Un-registered: @await Stats.GetUnRegisteredPersonCount()</p>
    <p>Total: @await Stats.GetPersonCount()</p>

That’s pretty cool! Isn’t it?

Tag Helpers

Another interesting thing in ASP.NET MVC 6 is the tag helpers. Tag Helpers are optional replacement for the previous HTML Helpers.

So if you are doing this before:

@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                <h4>Use a local account to log in.</h4>
                <hr />
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
                    <div class="col-md-10">
                        @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
                        @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" })

You can now instead do this:

<form asp-controller="Account" asp-action="Login" method="post" class="form-horizontal" role="form">
    <h4>Use a local account to log in.</h4>
    <hr />
    <div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="UserName" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input asp-for="UserName" class="col-md-2 control-label" />
            <span asp-validation-for="UserName" class="text-danger"></span>

That's pretty neat!

ASP.NET is not all about IIS

13 years ago, there was basically one web server for ASP.NET platform, and that was IIS. Few years later the Visual Studio Development Web Server (a.k.a "Cassini") came along as dev-only server. All of them ultimately used System.Web as the hosting layer between the application and the web server. The System.Web host is tightly coupled to IIS and is very difficult to run on other host.

Later on OWIN came around as an interface between application and web server. Microsoft wrote Katana as one OWIN implementation that could host ASP.NET Web API, SignalR, and other third-party frameworks on top of several servers, including IIS and IIS Express, Katana’s self-host server, and custom hosts.

ASP.NET 5 is host agnostic in the same manner as Katana and OWIN and any ASP.NET 5 application can be hosted on IIS, IIS Express or self-host in your own process. Adding to that ASP.NET 5 will include web server for IOS and Linux based operating systems called Kestrel built on libuv.

New HTTP Request Pipeline

ASP.NET 5 introduces a new HTTP request pipeline that is modular so you can add only the components that you need. The pipeline is also no longer dependent on System.Web. By reducing the overhead in the pipeline, your app can experience better performance and a more tuned HTTP stacks. The new pipeline is based on many of the learnings from the Katana project and also supports OWIN.

Dynamic Web Development

Another cool feature in Visual Studio 2015 is the ability to do dynamic compilation. In the previous versions of ASP.NET, when we change code in our application, we are required to compile and build the application every time we want to see the changes. In the new version of Visual Studio there’s no need to do those extra steps anymore instead you just have to save the file that you are modifying and then refresh the browser to see the changes.

Here’s the output after refreshing the browser:

Attribute Routing - the [controller] and [action] tokens

In previous versions of MVC and Web API, working with attribute routing may cause some troubles especially if you are doing some code refactoring. This is because the route always had to be specified as a string, so whenever you changed the name of the controller you would always have to change the string in the route attribute too.

MVC 6 introduces the new [controller] and [action] tokens that can resolved this kind of issue. Here's an excellent post that highlights the use of these new tokens: ASP.NET MVC 6 Attribute Routing

Integrated Dependency Injection (DI)

ASP.NET 5 has built-in support for Dependency Injection and the Service Locator pattern. This means that you no longer need to rely on third-party Dependency Injection frameworks such as Ninject or AutoFac.

Integration with Grunt, Gulp and Bower

Visual Studio 2015 has built-in support for these popular open-source web development tools. Grunt and Gulp are task runners that help you automate your web development work flow. You can use both for compiling or minifying JavaScript files. Bower is a package manager for client-side libraries, including CSS and JavaScript libraries.

Built-in Templates for AngularJS

AngularJS is one of the most popular client-side frameworks for building Single Page Applications (SPAs). Visual Studio 2015 includes templates for creating AngularJS modules, controllers, directives, and factories.

The support in ASP.NET 5 for GruntJS makes ASP.NET an excellent server-side framework for building client-side AngularJS apps. You can combine and minify all of your AngularJS files automatically whenever you perform a build.

Web.Config No More

In ASP.NET 5, the messy web.config file is being replaced with the new cloud-ready configuration file called "config.json". Microsoft wanted us developers to deploy apps in the cloud easier and have the app automatically read the correct configuration values for specific environment. Here’s an example of how the new config file looks like:

Since everything in ASP.NET 5 is pluggable then you need to configure the source for the configuration at Startup.cs class like:

public Startup(IHostingEnvironment env)
   // Setup configuration sources.
   Configuration = new Configuration()

xUnit.Net – The New Unit Test Tool for .NET

In previous versions of ASP.NET MVC, the default testing framework was the Visual Studio Unit Testing Framework (sometimes called mstest). This framework uses the [TestClass] and [TestMethod] attributes to describe a unit test.

ASP.NET 5 uses as its unit test framework. This framework uses the [Fact] attribute instead of the [TestMethod] attribute and removing the need of [TestClass] attribute].

Absolutely Free and Open Source!

Yes, ASP.NET 5 as an open source project on GitHub. You can view the code, see when changes were made, download the code, and submit changes.

I would agree that open-sourcing .NET makes good sense. It makes good business sense and good community sense. Big Thanks to Microsoft. Job well done!

PS: Some info listed on this article are based on Stephen Walther ASP.NET 5 post, make sure to check his blog here.