So this morning I found my self browsing through the images Microsoft has published in the Docker Hub and then I saw this one: microsoft/azure-functions-runtime and decided to Run a Precompiled .NET Core Azure Function in a Container.
Prerequisites:
Create a .NET Core lib project
Create a .NET Core lib project.
1dotnet new lib --name dni
2cd dni
3rm .\Class1.cs
Add the required references to be able to use Azure Functions API
Be sure to add the following packages to the project. I couldn’t make the sample work with the latest versions of some of the Microsoft.AspNetCore.* packages, so pay special attention to the version parameter.
1dotnet add package Microsoft.AspNetCore.Http -v 2.0.0
2dotnet add package Microsoft.AspNetCore.Mvc -v 2.0.0
3dotnet add package Microsoft.Azure.WebJobs -v 3.0.0-beta4
4dotnet add package Microsoft.Extensions.Primitives -v 2.0.0
5dotnet add package Newtonsoft.Json -v 10.0.3
Modify the Output Path of the project
Edit dni.csproj and the OutputPath property with the following value: wwwroot\bin. The project contents should now look like the following text:
1<Project Sdk="Microsoft.NET.Sdk">
2 <PropertyGroup>
3 <TargetFramework>netstandard2.0</TargetFramework>
4 <OutputPath>wwwroot\bin</OutputPath>
5 </PropertyGroup>
6 <ItemGroup>
7 <PackageReference Include="Microsoft.AspNetCore.Http" Version="2.0.0" />
8 <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
9 <PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta4" />
10 <PackageReference Include="Microsoft.Extensions.Primitives" Version="2.0.0" />
11 <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
12 </ItemGroup>
13</Project>
Create the wwwroot and validate folders
Create two folders. The first one wwwroot will hold all the functions and global configuration. The second one: validate will hold the configuration of the validate function we’ll be deploying.
1md wwwroot
2md wwwroot/validate
Create host.json file in the wwwroot folder
Create a host.json file in the wwwroot folder with the following contents:
1{ }
Create function.json and run.csx files
In the wwwroot/validate folder create a functions.json file with the following contents:
1{
2 "bindings": [
3 {
4 "authLevel": "anonymous",
5 "name": "req",
6 "type": "httpTrigger",
7 "direction": "in"
8 }
9 ],
10 "scriptFile": "..//bin//netstandard2.0//dni.dll",
11 "entryPoint": "Dni.HttpTrigger.Run",
12 "disabled": false
13}
Note that in functions.json we are specifying the function trigger type as httpTrigger and also specifying the scriptFile and entryPoint.
Now create a run.csx file with the following contents:
1//leave this file empty - all the logic is placed within our precompiled function
Create an HttpTrigger.cs file to hold your function
Create a HttpTrigger.cs file with the following contents:
1namespace Dni
2{
3 using System.Collections.Generic;
4 using System.Linq;
5 using Microsoft.AspNetCore.Http;
6 using Microsoft.AspNetCore.Mvc;
7 using Microsoft.Azure.WebJobs.Host;
8
9 public class HttpTrigger
10 {
11 public static IActionResult Run(HttpRequest req, TraceWriter log)
12 {
13 log.Info("DNI Validation function is processing a request.");
14
15 string dni = req.Query["dni"];
16
17 return dni != null
18 ? (ActionResult)new OkObjectResult(ValidateDNI(dni))
19 : new BadRequestObjectResult("Please pass a dni on the query string");
20 }
21
22 public static bool ValidateDNI(string dni)
23 {
24 var table = "TRWAGMYFPDXBNJZSQVHLCKE";
25 var foreignerDigits = new Dictionary<char, char>()
26 {
27 { 'X', '0'},
28 { 'Y', '1'},
29 { 'Z', '2'}
30 };
31 var numbers = "1234567890";
32 var parsedDNI = dni.ToUpper();
33 if (parsedDNI.Length == 9)
34 {
35 var checkDigit = parsedDNI[8];
36 parsedDNI = parsedDNI.Remove(8);
37 if (foreignerDigits.ContainsKey(parsedDNI[0]))
38 {
39 parsedDNI = parsedDNI.Replace(parsedDNI[0], foreignerDigits[parsedDNI[0]]);
40 }
41
42 return parsedDNI.Length == parsedDNI.Where(n => numbers.Contains(n)).Count() &&
43 table[int.Parse(parsedDNI) % 23] == checkDigit;
44 }
45
46 return false;
47 }
48 }
49}
Cause I didn’t want to create a simple Hello World sample, this Azure Function Code takes the dni parameter from the query string and validates if the given value is a valid Spanish National Identity Document number.
Create a dockerfile
Create a dockerfile with the following contents:
1FROM microsoft/azure-functions-runtime:v2.0.0-beta1
2ENV AzureWebJobsScriptRoot=/home/site/wwwroot
3ADD wwwroot /home/site/wwwroot
Note that once you execute a docker build on the file all the contents of the wwwroot folder will be copied to the /home/site/wwwroot inside the image.
Build the project and the docker image
Build the .NET Core project so you get a precompiled funtion and then build the docker image:
1dotnet build
2docker build -t dni .
Create a container and test the function
Run the following to run the Azure Function in a container:
1docker run -p 5000:80 dni
Now navigate to: http://localhost:5000/api/validate?dni=54495436H and the page should return true.
You can download all code and files here.
Hope it helps!
Comments