Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Getting Up To Speed with ASP.NET Core - A Sample Barebone MVC Application

0.00/5 (No votes)
10 Nov 2016 2  
In this article, I try to cover most basics of creating a portable (Windows, Mac and Linux) ASP.NET Core application and discuss possible use cases for a web app using ASP.NET Core.

Introduction

The .NET Core is out there, and there isn't much written about it yet. In this article, I try to cover most basics of creating a portable (Windows, Mac and Linux) ASP.NET Core application and discuss possible use cases for a web app using ASP.NET Core.

Background

If you're really going to read this, you need a basic understanding what the .NET Core is and how it is different from the classic ("real") .NET Framework.

I scrapped some resources on this topic together for you:

In the end, Scott is as always summing it up nicely:

Scott Hanselmann:

I feel like it's the culmination of all these years of work in .NET and Open Source. This is why I came to work at Microsoft; we wanted to open source as much as we could and build a community around .NET and open source at Microsoft. 15 years and the work of thousands of people later, today we released .NET Core 1.0.

[...]

The primary points of .NET Core are:

  • Cross-platform: Runs on Windows, macOS and Linux.
  • Flexible deployment: Can be included in your app or installed side-by-side user- or machine-wide.
  • Command-line tools: All product scenarios can be exercised at the command-line.
  • Compatible: .NET Core is compatible with .NET Framework, Xamarin and Mono, via the .NET Standard Library.
  • Open source: The .NET Core platform is open source, using MIT and Apache 2 licenses. Documentation is licensed under CC-BY. .NET Core is a .NET Foundation project.
  • Supported by Microsoft: .NET Core is supported by Microsoft, per .NET Core Support

.NET Core is composed of the following parts:

  • A .NET runtime, which provides a type system, assembly loading, a garbage collector, native interop and other basic services.
  • A set of framework libraries, which provide primitive data types, app composition types and fundamental utilities.
  • A set of SDK tools and language compilers that enable the base developer experience, available in the .NET Core SDK.
  • The ‘dotnet’ app host, which is used to launch .NET Core apps. It selects and hosts the runtime, provides an assembly loading policy and launches the app. The same host is also used to launch SDK tools in the same way.

Now Why Are You Supposed to Prefer ASP.NET Core Over A Classic ASP.NET Application?

Or more important: When?
There seem to be a million use cases in which one could use both. I'll focus on those that are clear. The following list is not complete by any means, but that's often true for many things in IT.

When to use ASP.NET Core? I'm unable to give you that "this is always true" answer. But let's look at an example:

The Canon Scanfront 400 is a small size industrial scanner developed by Canon. It can be used to scan documents of any kind, even passports and credit cards. They've published a video demonstrating its usage by a Hotel Front desk.

OMR applications (which can be used to process the scanned images) could be used to interpret certain values within the image (e.g. Passport or credit card numbers) and show the image snippet which needs verification on the scanner screen. The device itself runs on linux and could be programmed using Eclipse/Java, but this could get tedious. Instead of writing a specific program, one could just put an ASP.NET Core webpage behind it which displays the snippets and asks the user for verification actions. Big Plus on that one: You won't need to install yet another SDK. A self-hosted ASP.NET Core app could even be used within medical applications (for example, reading laboratory orders and feeding them into a laboratory information system) without the need to effectively install (and even more costly: maintain) an IIS server - Any sysadmin is sceptical when you tell him "Hey, we're going to need another Server / another app instance".

That one brings up the main point already: If you have a small web app and develop it as a standalone app which doesn't need an IIS, your chance of selling it to a customer that doesn't have an IIS on site increases dramatically.

In short: ASP.NET Core is a possible solution wherever/whenever the environment the Web App is going to run within is:

  1. platform-independent (Customer A runs it on Linux, customer B on Windows) or
  2. strictly regulated (Defense, Medical or financial environments) or
  3. there is just no know-how of how to maintain an IIS instance (or lack of time to do that, respectively)

Let's Get Started Already

But first, check whether you're ready to go or not. ASP.NET Core needs some prerequisites to run - Check them at the .NET Core page. The page is automatically showing you what you need to develop to ASP.NET Core using the system you use to browse the site.

If you have installed all the tools you need from the .NET Core page, open Visual Studio and create a new Console application for .NET Core:

If you have everything set up correctly, you can see the .NET Core sub section in the Templates Treeview of the Create Project wizard.

From there, select Console Application (.NET Core)
Side Note: This article is about getting started with ASP.Net core and if you'd really want to get your hands on it you'd probably select ASP.Net Core Web Application.

After you created the project, you can see the project structure in the Solution Explorer as pictured above. First and foremost, we have to lay our attention to the project.json file. At the start, the file looks like this:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true
  },

  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.1"
    },
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }
}

The file is used by the .NET Core Tools to determine assembly metadata, dependencies an other stuff. It's huge what you could do with it, and explaining it in detail would go far above this article's scope. If you're interested in learning more, have a look at the documentation.

Anyways, the first step to convert our console application into an ASP.NET Core application is to setup a dependency to the Microsoft.AspNetCore.Server.Kestrel namespace. Just paste in the bold line in the snippet below:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true
  },

  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.1"
    },
    "Microsoft.AspNetCore.Server.Kestrel":"1.0.0"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }
}

What's Kestrel? From the Microsoft Docs:

docs.asp.net:

Kestrel is a cross-platform web server based on libuv, a cross-platform asynchronous I/O library.

In essence: ASP.NET Core can be hosted in IIS or IIS Express, but doesn't rely on either one of them. That's where Kestrel comes into play: It's not a replacement, but a feasible alternative if you can't host the app in IIS or IIS Express, even though the docs mention using them as reverse proxies. I won't give you more details on that, if you want to have a deeper look the ASP.NET Core, server documentation page is a great source of knowledge.

Hello from Kestrel

Now that we added the dependency to Kestrel, we can proceed to make it come alive (it will be only barely alive, though). First, add a class named Startup to the console application. Replace its using directives with those two:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

Afterwards, replace the class with the following snippet:

public void Configure(IApplicationBuilder app)
        {
            app.Run(context => {
                return context.Response.WriteAsync("Hello from Kestrel");
            });
        }

All the snippet does is really simple: reply "Hello from Kestrel" to any request that comes to your web app. The Web App now knows what to reply, but at this moment, all we got is still a simple Console app. In order to convert it to a Web App (well, at least a really barebones one), we'll need to modify the Program.cs file:

Add the following snippet to your Main method:

Console.WriteLine("A moment please - Preparing the Kestrel Host");

var host = new WebHostBuilder()
            .UseKestrel()
            .UseStartup<Startup>()
            .Build();

Console.WriteLine("Ready to go");
host.Run();

For this to work, you'll need to put...

using Microsoft.AspNetCore.Hosting;

...at the top of the Program.cs. These lines tell our Console App to start a Web Host using Kestrel which uses our Startup class as entry point (Index page). All that looks like this once we build our project:

Once you read "Application started", go to http://localhost:5000 to see if it is working as intended and the Startup class is returning what you've told it to:

Congratulations! You've created the bare bones of an ASP.NET Core Web App, hosted from the console. It's still dumb, and to really get an advantage from it we'll need to bring MVC into play. Read ahead.

Would You Like MVC With That?

The example we created so far is only a feasibility study (at best, but barely) that shows ASP.NET Core's capability returning a bare string to a request it gets. That is, especially in today's day and age of web, not a big deal and provides not even the fundamentals of what a web app consists of in today's understanding. MVC is the way to go - Follow me!

Go back to the project.json file we modified earlier in this article.

{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true
  },

  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.1"
    },
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.AspNetCore.Mvc": "1.0.0"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }
}

Add the line "Microsoft.AspNetCore.Mvc": "1.0.0" (written in bold in the above sample) just below the Kestrel dependency. Don't forget to add the comma in the line above, too. As soon as you save the project.json, Visual Studio will restore the dependencies for you. Now that the dependencies are set within project.json, we need to pay some attention to our Startup class since all MVC initializations will happen there.

First of all, add...

using Microsoft.Extensions.DependencyInjection;

...to the using directives. Why? .NET Core will automatically use the latest Microsoft Framework to perform dependency injections, therefore the using directive. Now change the intestines of your class to the following (changes in comparison with the previous class content are marked bold):

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc();

            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello world");
            });
        }
    }

ConfigureServices gives you the chance of registering any service or dependency required by your application. In this case, services.AddMvc() is a shorthander to configure all the services provided by Microsoft's .NET Framework implementation.

Controllers

Now that we've thrown in the basic prerequisites for our app to use MVC, let's add a Controller. ASP.NET Core doesn't force you to keep your Controllers in the Controllers folder, but for the sake of not recreating the wheel, I'll just stick with it.

I've created a class named HelloController in the ContactApp project.

Now to transform that class into a Controller, I need to derive from the Controller class (obviously).

using Microsoft.AspNetCore.Mvc;
using System;

namespace ContactApp.Controllers
{
    public class HelloController:Controller
    {
        [Route("hello/index")]
        public IActionResult Index()
        {
            return Ok($"Hello there. It's {DateTime.Now}.");
        }
    }
}

Now compile your app and go to http://localhost:5000/hello/index. You will see the Greeting message from below, generated by your first ASP.NET Core Controller.

Data? View? Whatcha Getting There?

In fact - Anything. ASP.NET Core doesn't care whether you're returning a View or Data. To it, everything is an IActionResult. If we modify the example above to return a class, the IActionResult will be JSON data. Cool, huh?

public class HelloController:Controller
    {
        [Route("hello/index")]
        public IActionResult Index()
        {
            return Ok(new TestClass("Hi there", "It's after 10 PM here"));
        }
    }

    public class TestClass
    {
        public TestClass(string s1, string s2)
        {
            S1 = s1;
            S2 = s2;
        }

        public string S1 { get; set; }
        public string S2 { get; set; }
    }

The resulting output will be a JSON string, formatted as:

{"s1":"Hi there","s2":"It's after 10 PM here"}

Of course, not everyone is familiar with JSON, and the average Joe Webuser certainly isn't. To make our data visible to average Joe, there is no way around creating a view. To make your first one, create the Folder Views/Hello in the ContactApp project. ASP.Net Core will look for views in predefined places, and the Views Folder is the most common one.

Afterwards, modify your HelloController to return a View on the Route hello/greet with the optional parameter username.

public class HelloController:Controller
    {
        [Route("hello/index")]
        public IActionResult Index()
        {
            return Ok(new TestClass("Hi there", "It's after 10 PM here"));
        }

        [Route("hello/greet/{username?}")]
        public IActionResult UserName(string username = "you over there")
        {
            return View(new TestClass (username, DateTime.Now.ToString()));
        }
    }

If the username parameter isn't set, "you over there" will be used as default user name. Now go ahead and add a file named UserName.cshtml to the Views/Hello folder of the ContactApp project.

<div>
    <h1>Hello @Model.S1</h1>
    <h3>It's @Model.S2</h3>
</div>

Now before the example we created is going to run, we'll need to adjust a few things. First of all, add the line

"preserveCompilationContext": true, right below buildOptions in your project.json file:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "preserveCompilationContext": true,
    "emitEntryPoint": true
  },

Afterwards, switch over to Program.cs and add UseContentRoot(Directory.GetCurrentDirectory()) right after UseKestrel:

var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseStartup<Startup>()
            .Build();

Why did we have to adjust that? The change in the project.json is an adjustment to tell the compiler to preserve certain referenced assemblies (for example System) in order for Razor to compile your views at runtime. The change we needed to make in our Program.cs tells the web server where it needs to look for content files (views, for example).

Now after we've done all of this, let's run the project and see the outcome:

At the left side, the output from the view using Marco as username parameter is shown.

Below, there is the output shown from the same controller, but without a user name parameter. It therefore "you over there" is being used as the default.

Further Reading

Whilst I gave my best to bring you a basic understanding of what ASP.NET Core is, how it works and when you might come to find it usable, I did not go into too much detail in order to keep this entire article on topic. If you find a need to read further after you finished reading my article, you will find more stuff in the links below. I've used them during my research for this article and they were a great source of knowledge. May they be of use to you the way they've been of use to me.

At this point, I can only recommend reading any post from Scott Hanselmann on ASP.NET Core.
He did not only a great job in promoting the new technology, but also in explaining the why's of it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here