Earlier I wrote about ASP.NET Core MVC from scratch as well as ASP.NET Core Routing as part of my learning the fundamentals of ASP.NET Core. I am developing these examples without Visual Studio. Instead, I am using Visual Studio Code on macOS.

In the ASP.NET Core Routing example I created an implementation of IRouter to handle Fibonacci number requests. This isn't the only way to handle incoming requests for a particular route. I could have used RouteBuilder.MapGet, which also accepts a template string, but instead of an IRouter, I can just just provide a RequestDelegate to handle the requests.

I am going to use RouteBuilder.MapGet to return a factorial very similar to how I used an impementation of IRouter to return Fibonaaci numbers.

dotnet CLI

First things first, I need to create a new directory for this ASP.NET Core Web Application, issue a few dotnet CLI commands to build the initial application framework, and open the application in Visual Studio Code.

mkdir FactorialAPP && CD $_

dotnet new
dotnet restore

code.

Project.json - ASP.NET Core

As you saw from the ASP.NET Core Routing and fibonacci tutorial, I need to add 2 dependencies to project.json: Microsoft.AspNetCore.Server.Kestrel and Microsoft.AspNetCore.Routing. Kestrel is the cross-platform web server and I need ASP.NET Core Routing to provide custom routing for incoming factorial requests. Once I add these new dependencies I execute another dotnet restore command from within Visual Studio Code to install the Nuget Packages.

{
  "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",
        "Microsoft.AspNetCore.Routing": "1.0.0"
      },
      "imports": "dnxcore50"
    }
  }
}

Startup

All .NET Core applications are console applications. I need to instantiate a web host using WebHostBuilder. Kestrel is the web server and the Startup Class will be the entry point for the ASP.NET Core Web Application.

using Microsoft.AspNetCore.Hosting;

namespace FactorialApp {
    public class Program {
        public static void Main(string[] args) {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseStartup()
                .Build();

            host.Run();
        }
    }
}
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;

namespace FactorialApp {
    public class Startup {
        public void ConfigureServices(IServiceCollection services) {
            services.AddRouting();
        }

        public void Configure(IApplicationBuilder app) {

            var rb = new RouteBuilder(app);

            RequestDelegate factorialRequestHandler = c => {
                var number = c.GetRouteValue("number") as string;

                int value;
                if (Int32.TryParse(number, out value)) {
                    value = Math.Abs(value);
                    var results = Factorial.Calculate(value);
                    return c.Response.WriteAsync($"{number}! = {results}");
                }

                return c.Response.WriteAsync("${number} is not an integer.");
            };

            rb.MapGet("factorial/{number:int}", factorialRequestHandler);

            var routes = rb.Build();

            app.UseRouter(routes);
        }
    }
}

As I have mentioned before, the services.AddRouting() statement just adds ASP.NET Core Routing assets to the built-in dependency injection framework offered by ASP.NET Core.

The Configure Method is where I need to configure the new routes. The key in this example is the creation of a RequestDelegate, called factorialRequestHandler. This will handle all incoming requests to calculate a factorial.

This delegate is wired up to handle route requests using the RouteBuilder.MapGet method.

rb.MapGet("factorial/{number:int}", factorialRequestHandler);

I added a constraint on the route such that number must be an integer.

One can now request the factorial of a number using the following request.

http://localhost:5000/factorial/15

Factorial Calculation

The calculation of the factorial is a simple recursive function.

using System;

namespace FactorialApp {
    public static class Factorial {
        private static Int64 CalculateFactorial(int number) {
            if (number < 2)
                return 1;

            return number * CalculateFactorial(number - 1);
        }
        public static Int64 Calculate(int number) {
            return CalculateFactorial(number);
        }
    }
}

Running the ASP.NET Core Web Application

I run the application and request the factorial of 15.

dotnet run

Project FactorialApp (.NETCoreApp,Version=v1.0) will be compiled because Input items removed from last build
Compiling FactorialApp for .NETCoreApp,Version=v1.0

Compilation succeeded.
    0 Warning(s)
    0 Error(s)

Time elapsed 00:00:01.0155552
 

Hosting environment: Production
Content root path: /Users/Sasquatch/Projects/Core/FactorialApp
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

ASP.NET Core Routing Tutorial Calculating a Factorial

Conclusion

This is slick! I promised myself I would extend these examples in a couple of ways. I want to do this using Flask and Python, and I want to do this using ASP.NET Core Web API. I also want to write a simple Python client that requests several factorials. Lots of cool stuff on my list. I hope this tutorial is useful to you in your pursuit of knowledge!

Posted by Koder Dojo

Welcome to Koder Dojo. This website is filled with many examples on Python and ASP.NET Core. Come learn with me as I learn .NET Core, ASP.NET Core, and ASP.NET Core MVC that was just released from Microsoft. If you are more into Python, I am attending several online courses that use Python: computer science, algorithms, data structures, and cryptography. All this is happening in addition to my day job as a freelance ASP.NET MVC C# Developer. This is seriously fun!

Related Posts: