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
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.
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!