ASP.NET Core : Ragnarok

Once upon a time

There was a drag/drop interface dragon of a web development framework in our beloved .NET ecosystem, it was called WebForms. It was lovely for its time, until the web began to evolve. The world began to hate it for everything, the monster was hard to maintain, hard to scale and to compile a large applications took as much time as it took a hundred JavaScript frameworks to be released. It was time for developers to move on. The overlords were unhappy and decided to create something new, something that they think is what we asked for. A dragon, they called it ASP.NET MVC. It was very beautiful and also had a younger sibling called the WebPages that appeased to those who had run off and those coming from languages such as PHP. Things were changing real fast and apps started breaking. Even fanboism could not stop the majority from considering other frameworks, OS-bias didn't allow other platform users to try it. They only heard of this great dragon but never knew of its power. Even frameworks that preceded it and those that took the form of jewels and snakes soured higher without wings. They could adapt to any environment and all you needed to begin was a simple text-editor and an apt-get command spell. It was pretty straight-forward, it broke the smile off the faces of many who had hoped that this new dragon was powerful enough to reign fire over the new kids. Even the need for an IDE which wielded as much power as the Excalibur could not save it. The people were clear on what they wanted, the overloads must have misinterpreted but we always trusted that one day they would create something loveable, something that does not suffer from OS-bias, something that everyone could contribute to, something that a simple save command would effect changes. They listened!!!

A note of warning; this article was written while I was eating a bowl of Jollof.

Present day (2016 AD) - In the beginning was the core.

Microsoft has just announced a web application framework that's runs on its open-sourced .NET platform. It gives you the power to create a web application that's modern. You basically do not have your application tied to the entire .NET ecosystem but only as much as you needed for your application to work. Creating a web application with .NET core does not feel any different from creating a web application with any modern framework such as NodeJs, Ruby or even PHP (with composer); Download and install .NET Core here and VS Code here

Your first .NET Core application

Creating a simple .NET Core app requires three of the most complicated commands in the world. Fire breathers, if I may add. Open your choice command window (powershell, cmd, bash, zsh) and type carefully because a simple mistake could wreck your computer. I am using a windows machine but these commands should all be the same on other OSes. Please let me know of differences in the comment section

mkdir firstapp # creates the folder for your firstapp  
cd firstapp # gets you into the folder  
dotnet new # creates a new dotnet application for you.  

Around a million files should be in the app folder by this time. So lets use simple command to open it in VS Code code . - there's a period(.) there, yeah right there. That's why it didn't work the first time.
If you see a million files, you definitely did something wrong you are on your own and I was only kidding you about those commands. You should only have two files at this point. To run your application for the first time you have;

dotnet restore # downloads all dependencies as required in the project.json file  
dotnet run # application is compiled and a bin folder is created - Hello World!  

What you have succeeded in doing is create something that is commonly referred to as dotnet core console (or cli) app. Feel free to mess with it for various results. This is no different from having a NodeJs console application. You might also notice that subsequent runs of same code skips compilation.
Image of first app compilation
From here on for the sake of comfort, you might want to use the built-in command window in Visual studio code or your preferred text-editor/IDE.

Ragnarok

ASP.NET Core is the latest of the ASP.NET line. It was rebuilt from scratch to take advantage of the .NET Core framework. Making the resulting web application very modular and not tied to the Full .NET framework which by the way is not available to other platforms except maybe through Mono. Our firstapp .NET Core is however available cross-platform. Our console application can be converted to a web application with just a little extra work.

Your First ASP.NET Core application

We'll start with making a few changes to the Program.cs file. Its the entry-point for our application. Lets' do this!!!
300 Spartans

//Program.cs

using Microsoft.AspNetCore.Hosting;  
using System.IO;

namespace FirstApp  
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseStartup<StartUp>()
            .Build();

            host.Run();
        }
    }
}

You should have a couple of red squiggly lines if you are using a text-editor with Intellisense. Worry not, we are not done. Next create a new file and name it StartUp.cs. Below is the content of the file.

// Startup.cs 

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

namespace FirstApp  
{
    public class StartUp {
        public void Configure(IApplicationBuilder app)
        {
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Nigerian Jollof is the best!");
            });
        }
    }
}

Lastly, we go over to our project.json file to add some new dependency on the Kestrel sever middleware.

// Project.json

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0"
        },
         "Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
      },
      "imports": "dnxcore50"
    }
  }
}

Now, restore dependencies and run your application. Go to your browser and visit http://localhost:5000 and you should have running in your browser a web application that tells you a honest fact about Jollof rice "Nigerian Jollof is the best!" which you just have to agree to :-);

The honest truth

Serving static files

Now that we're here, we've been doing a lot of this the hard way. Let me make life easier for you.

  • Install Yeoman and aspnet project template generator.
npm i -g yo generator-aspnet  
  • Generate and run your first asp.net core application
yo aspnet # Generates the asp.net template (I know it's not our first)  
  • You'll get a set of options select the Empty web application project.
    Enter the name of the application and hit enter to continue.

Application Name

dotnet restore  
dotnet run # Launches application on http://localhost:5000  
  • This creates an application similar to the one above for you with quite a bit more files and using statements. All this would have cost us time to write but phew, thanks to Yo!. Now lets do a bit more to make it emit exactly the same result as our above example before we continue. Replace the app.Run() section of the Configure method.
// Startup.cs

using Microsoft.AspNetCore.Builder;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.AspNetCore.Http;  
using Microsoft.Extensions.DependencyInjection;  
using Microsoft.Extensions.Logging;

namespace MyFirstWebApp  
{
    public class Startup
    {
        //... Code removed for brevity

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Nigerian Jollof is the best!");
            });
        //... Code removed for brevity
    }
}
dotnet restore  
dotnet run  

Open your browser and bam!!! The Fact strikes again!!!
Now that we are back to where we were (actually we are a little further than that), Let's see how we can imitate the serve static files of old. Go over to your project.json file and add a new dependency (StaticFiles middleware) as show below and restore.

//Project.json
{
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    },
  //... removed for brevity
    "Microsoft.AspNetCore.StaticFiles": "1.0.0"
  },

 // ... removed for brevity
}

Now add a new file called index.html to the wwwroot folder. Populate it with the below code.

<!-- index.html -->  
<!DOCTYPE html>  
<html lang="en">  
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        Nigerian Jollof is just too powerful.
    </body>
</html>  

Go to your Startup.cs file, remove the app.Run() section in the Configure method and add app.UseFileServer() to make use of the middleware. See the resulting code below.

//Startup.cs
//... code removed for brevity
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)  
        {
            loggerFactory.AddConsole();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseFileServer();
        }
// ... code removed for brevity

Run the application and refresh your browser and you'll end up with a powerful message from yours truly. The wwwroot is where all static files and front-end codes goes. So in the future you might be creating a js and styles folder else you'd have to make use of the StaticFiles service to map a new Directory to serve static files from.

A powerful message

Creating an MVC application

You've come this far, why give up!
Why give up

At this point, you already know how to add new dependencies. So add a new dependency on Microsoft.AspNetCore.Mvc and restore. Now you have all you need to create a basic MVC application with routing support. Lets quickly test this out.

First create a couple of folders to hold your first controller and its view, one called Controllers and another called Views. In the Views folder create a folder called Home.

Folder Structure

Lets' go over to our Startup.cs and tell our application about our new MVC middleware and use it instead.

// Startup.cs
// ... Code has been removed for brevity

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

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)  
{
    loggerFactory.AddConsole();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseMvc(options =>{
        options.MapRoute("Default", "{Controller=Home}/{Action=Index}/{id?}");
    });
}

// ... Code has been removed for brevity

That done, we now have to create our controller. Create a new file file called HomeController.cs within the Controllers folder.

// HomeController.cs
using Microsoft.AspNetCore.Mvc;  
namespace MyFirstWebApp  
{
    // Executes without the need for a view file
    public class HomeController: Controller {       
        public string Index(){
            var model = "Hello Jollof!";
            return model;
        }

        // Would require a view (Jollof.cshtml)
        public IActionResult Jollof(){
            var model = "Hello Jollof!";
            return View("Jollof",model);
        }
    }
}

Now go over to the views folder and create a Jollof.cshtml file.

<!-- Jollof.cshtml -->  
@model String

<!DOCTYPE html>  
<html lang="en">  
    <head>
        <meta charset="UTF-8">
        <title>Facts</title>
    </head>
    <body>
        <h1>@Model</h1>
    </body>
</html>  

Now visit http://localhost:5000/home and http://localhost:5000/home/jollof to see what you've achieved so far.

...and an API Service

One More!

One More

Creating an API Controller from what we already have set-up is pretty straightforward but lets at least have a model to serve to the users.

We'll make all the changes we need to the HomeController.cs, no need for any extra unnecessary work and dependencies restores etc.

//HomeController.cs

using System.Collections.Generic;  
using Microsoft.AspNetCore.Mvc;

namespace MyFirstWebApp  
{
    public enum Rating
    {
        Poor,
        Good,
        VeryGood,
        Excellent
    }

    public class Menu
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Rating Rating { get; set; }
    }

    public class HomeController : Controller
    {
        public string Index()
        {
            var model = "Hello Jollof!";
            return model;
        }
        public IActionResult Jollof()
        {
            var model = "Hello Jollof Again!";
            return View("Jollof", model);
        }

        [Route("api/menu")] //attribute routing
        public IActionResult Menu()
        {
            var model = new List<Menu>()
            {
                new Menu{
                    Id = 1,
                    Name = "Nigerian Jollof",
                    Rating = Rating.Excellent
                },
                new Menu {
                    Id = 2,
                    Name = "Amala",
                    Rating = Rating.VeryGood
                },
                new Menu {
                    Id = 3,
                    Name = "Ghanaian Jollof",
                    Rating = Rating.Poor
                }
            };

            return new ObjectResult(model);
        }
    }
}

Now using your browser or preferably postman go to http://localhost:5000/api/menu and you should find a json result of your your menu. Somewhere in the code you must have noticed this [Route("api/menu")]. It's called attribute routing and it's a way of specifying in-line how your routes should look like in other to hit the controller. In our case we've used it to tell our app that when api/menu is requested, ignore the default route and display the menu list.

postman

Conclusion

And the overloads smiled because their creation this time will be able to put smiles back on the faces of .NET web developers and those who would want to try it out. This new creation comes with magical powers that makes life simple once again, just like in the days of WebForms. Oh the Irony.

Go ye forth into the world with this new power and create apps that are truly magical. The documentation is your trusted manual to conquer.

documentation

THE END!!!

Show Comments