如果你想学习如何构建 Azure 函数,这里有一个有趣的项目。这个项目有点傻,但是很有教育意义。
我们将构建一个二维码生成器,它在 Azure 函数中100% 运行。互联网上有成千上万的二维码生成器,所以这是一个愚蠢的练习,但我想挑战 Azure 函数的极限,向你展示它们是多么的酷,并激励你用它们创建很酷的东西。
如果你更喜欢看视频,我们这里有完整的教程:
这会很有趣的,我希望你能跟着我学习。我们将在这个教程中做什么:
在本教程的最后,您将拥有一个功能性的二维码生成器,它可能会激发您使用 Azure 函数构建更酷的东西。它们结构紧凑、简单、易于构建。
您可以在这里找到该项目的完整源代码。
Azure 函数是运行在 Azure 中的无服务器应用程序。它们是可以在没有服务器或复杂实例的情况下执行的小块代码。大多数 Azure 函数都是“微服务”,它们完成一个小任务,并且做得很好。
Azure 函数还可以响应 HTTP 触发器,作为一种“迷你 API”它们像 Web API 一样响应 HTTP 请求,但是使用函数的设置要少得多。
我开始听起来像一个广告,但它是令人敬畏的。几年前,这个项目要求您在某个 IIS 服务器上设置服务器或 ASP.NET Web API。现在我们只需要几行代码就可以做到这一点,并将其推送到云端。Azure 函数允许你专注于构建很酷的东西,而不是所有的设置。
以下是本教程所需的内容。我将在 windows11中构建它,但我们不使用 VisualStudio。我将使用这个 dotnet 驱动程序,所以您可以在 mac 或 OSX 上复制它,如果您愿意的话。你必须在你的机器上安装这个(免费的)软件。
你需要:
我们开始吧!
我们将使用 Azure CLI 为我们创建一个新的 Azure 函数,我们将使用 dotnet 驱动程序来安装软件。
VisualStudio 可以为我们实现自动化,但是这样做可以更好地了解所涉及的步骤,并且可以在许多平台上完成。
首先,我们将初始化一个新函数。我们将使用 func 命令创建一个名为 QRCodeGen 的新项目。我们将工作者运行时指定为“ dotnet”来选择 C # 作为所使用的语言。
在项目或存储库文件夹中运行此命令:
Shell
func init QRCodeGen --worker-runtime dotnet
如果你看一下文件夹,里面没什么东西:
我们仍然需要在项目中创建一个 Azure 函数。Azure 函数有一组模板,这取决于您正在开发的应用程序的类型。我们希望创建一个 HTTP 触发器,一个响应 HTTP 请求的函数。
Shell
func new --template "Http Trigger" --name QRCodeGen --authlevel anonymous
如果您正在使用 VisualStudio 代码,您可能会看到以下消息:
选择 yes 来安装扩展。
现在您将看到 func 为您创建的一个示例函数:
如果您想尝试,可以在本地运行它
Shell
func start
然后您将看到函数启动,控制台将向您提供一些关于如何使用应用程序的指导:
正如我们所看到的,我们可以向
http://localhost:7071/api/qrcodegen 发送 GET 或 POST。让我们在浏览器中加载它,看看一个简单的 GET 返回什么:
我们有一条信息显示:
This HTTP triggered function was executed successfully. Pass a name in the query string or in the request body for a personalized response.
好的,让我们深入研究一下代码,看看这条信息是什么意思。
C#
string responseMessage = string.IsNullOrEmpty(name)br ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."br : $"Hello, {name}. This HTTP triggered function executed successfully.";
正如您在上面的代码中看到的,它正在检查名称中的值。如果该变量为空或 null,它将显示我们刚才看到的消息。
但我们如何填充这个值呢?几行之后,我们在查询中看到一个可以使用的参数:
C#
string name = req.Query["name"];
如果它被填充,它将显示一条包含名称的消息。我们需要向它发送一个 URL,名称作为一个参数,如下所示:
http://localhost:7071/api/QRCodeGen?name=Jeremy
让我们试试这个:
这是我的留言。现在我们知道函数正在按预期工作。我们加载一个 URL,获取参数并修改输出。
为了简单起见,我们将把这个模型用于我们的二维码生成器。我们将建立监听请求的 URL,并在 GET 命令中传递该值,然后返回一个二维码。让我们从生成二维码开始。
将文本转换成二维码是相对复杂的。幸运的是,你在吸毒。NET.你不必手工制造发电机。这个问题很久以前就解决了。我们将使用库生成一个。我们的 PNG 二维码。我们只需要围绕它编写一些代码,并构建一个工具来解决我们的问题。
首先,让我们从 Manuel BL 安装 QRCode Generator 包。我们会使用网络驱动程序。我将在撰写本文时指定最新版本。
Shell
dotnet add package Net.Codecrete.QrCodeGenerator --version 2.0.1
QRCode 生成器工作得很好,但只能生成。Svgs.因为我们想要一个。PNG (位图)格式,并希望它在多种环境下工作,我们需要安装 SkiaSharp 软件包:
Shell
dotnet add package SkiaSharp
SkiaSharp 包含了生成位图的功能,但是你必须下载并将这个文件添加到你的项目中:
https://github.com/manuelbl/QrCodeGenerator/blob/master/Demo-SkiaSharp/QrCodeBitmapExtensions.cs
在项目文件夹中创建一个名为 qrcodebitmapextensions.cs 的文件,并将该文件的内容复制到该文件中。这将允许您使用位图,特别是。PNG 文件。
现在我们有了 QR 码生成工具,让它在函数中工作吧。
如果你打开 QRCodeGen.cs,你会看到为我们生成的 Azure 函数(一个方法) ,它看起来像这样:
C#
[FunctionName("QRCodeGen")]br public static async Task<IActionResult> Run(br [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,br ILogger log)br {br log.LogInformation("C# HTTP trigger function processed a request.");brbr string name = req.Query["name"];brbr string requestBody = await new StreamReader(req.Body).ReadToEndAsync();br dynamic data = JsonConvert.DeserializeObject(requestBody);br name = name ?? data?.name;brbr string responseMessage = string.IsNullOrEmpty(name)br ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."br : $"Hello, {name}. This HTTP triggered function executed successfully.";brbr return new OkObjectResult(responseMessage);br }
让我们删除这个方法:
C#
namespace QRCodeGenbr{br public static class QRCodeGenbr {brbr }br}
接下来,让我们添加一个生成 QR 码的新方法。
首先,添加名称装饰器。这将为方法提供一个名称并更改 URL 以访问它。
C# C #
[FunctionName("GenerateQRCode")]
现在,当我们运行我们的应用程序,网址将是:
http://localhost:7071/api/GenerateQRCode
这将是我们调用来生成二维码的 URL,我们将从 JAVAScript 调用它。
接下来,创建方法:
C#
public static async Task<IActionResult> Generate(br [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)br {brbr }
我们正在创建一个名为 Generate 的方法,我们传入一些参数来告诉应用程序我们需要一个 HttpTrigger:
[HttpTrigger
在这个触发器中,我们传递了一些参数。
我们希望将授权设置为匿名,以便任何人都可以访问它:
AuthorizationLevel.Anonymous
我们只想接受对此 URL 的 GET 请求,因此下面的参数指定:
"get",
然后我们将路线设置为空。如果我们想要一个不同的 URL 或特定的路由,我们可以在这里指定它。为了简单起见,我们就让它保持原样:
Route = null)]
接下来,我们将传入一个 HttpRequest 对象。这将包含来自传入请求的数据,以便我们可以从中获取参数。当一个 GET 请求被发送到我们的函数中时,我们可以提取头、参数等信息。
HttpRequest req
最后,我们将传入一个日志记录器,以便能够记录消息。
ILogger log
很好,现在我们已经构建了方法,让我们填写它。
用户必须发送他们想要转换成二维码的文本。通常是个网址。我们很早就决定让事情变得简单。我们将从发送到 API 的查询字符串中收集这些信息。
还记得我们传递给方法的 HttpRequest 吗?我们可以从中得到 Query 参数。我们可以建立一个字符串变量,然后从查询字符串中获取参数:
C#
string qrtext = req.Query["qrtext"];
添加以下消息以记录输出。我们想显示发送到 qrtext 变量的内容:
C#
log.LogInformation("Generating QR Code for {0}", qrtext);
这样,我们就可以复查发送的内容了。
现在,让我们生成我们的二维码。
接下来,我们需要获取字符串,将其编码为二维码,然后将其导出为 PNG。
因此,我们将对之前安装的 QRCode 库进行静态调用。我们将传入要生成的文本和错误纠正值。中号就可以了。
C#
var qr = QrCode.EncodeText(qrtext, QrCode.Ecc.Medium);
这就是生成二维码的全部过程。但它是 SVG 格式的。我们需要把它转换成一个 PNG,这样我们就可以显示它。
由于我们在上面添加了位图扩展,现在我们的 QR 对象有一个方法可以将 QR 代码转换成带有一些参数的 PNG。
我们需要添加一个比例: 我使用了10,这似乎产生了一个不错的大小。
我用1表示边界。
然后我将前景(代码)设置为 SKColors。黑色,背景设置为 SKColors。白色。
输入密码如下:
C#
var pngout = qr.ToPng(10, 1, SkiaSharp.SKColors.Black, SkiaSharp.SKColors.White);
现在我们有了二维码。太简单了!现在让我们将其打包为 JSON 并发送出去!
我们一直在公共静态类 GenerateQRCode 中创建此代码。让我们创建另一个类,它将创建一个简单的对象,我们可以在调用 API 时返回这个对象。
在 GenerateQRCode 类的外部(在最后一个}之前)创建一个 Return nObject 类。
这个类只有一个名为 Image 的属性。这将是一个字符串,我们将把 PNG 编码为文本。
C#
public class ReturnObject {br public string Image { get; set; }br}
现在回到 GenerateQRCode 类,让我们回到刚才的地方,我们将创建一个新的 Return nObject:
C#
var ourResult = new ReturnObject{};
现在,我们将 PNG 映像转换为 Base64字符串,并将该字符串添加到返回对象中:
C#
ourResult.Image = Convert.ToBase64String(pngout);
放松。现在我们将把 POCO (普通的旧类对象)作为一个新的 JsonResult 返回,因此它将 JSON 返回给调用者:
C#
return new JsonResult(ourResult);
就是这样。在大约七行代码中,我们将一个字符串转换成二维码,然后将其发送出去.
我们来试试。
我们将启动这个函数并让它在本地侦听。我们将发送一个带有查询的 GET 请求来测试它。
在命令行中键入以下内容:
Shell
func start
启动函数。
你应该看看这样的东西:
现在我们将向
http://localhost:7071/api/GenerateQRCode
请记住,我们在代码中指定的参数是 qrtext,因此我将把它添加到最后:
http://localhost:7071/api/GenerateQRCode?qrtext="hello world"
我正在使用 Postman 进行此操作,因此可以看到呈现的 JSON:
我们所做的日志记录表明,它呈现的是“ hello world”:
所以步骤很简单:
这是我们目前输入的所有代码:
C #
public static class QRCodeGenbr {br [FunctionName("GenerateQRCode")]br public static async Task<IActionResult> GenerateQRCode(br [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)br {br string qrtext = req.Query["qrtext"];br log.LogInformation("Generating QR Code for {0}", qrtext);brbr var qr = QrCode.EncodeText(qrtext, QrCode.Ecc.Medium);br var pngout = qr.ToPng(10, 1, SkiaSharp.SKColors.Black, SkiaSharp.SKColors.White);
这很棒,但我们还没完。我们还需要部署它。但在此之前,让我们构建一个小型的、简单的 JavaScript 前端来与这个函数交互。
我们希望这个二维码生成器是完全独立的。尽管 Azure 函数并不是真正用来提供网页服务的,但它是可能的。在这种情况下,我们可以设置它,这样就不需要在其他地方托管前端。这只是一个简单的网页,所以让我们提供它。
首先,我们将创建index.html。
创建一个名为 www 的文件夹并创建一个名为 index.html 的文件。
这将是一个超级简单,粗糙的前端ーー没有什么花哨的,只是足以完成工作。
在顶部加入以下内容:
HTML
<!DOCTYPE html>br<html>br<body>brbr<h2>QR Code Generator</h2>
这是我们的基本标题。接下来,我们需要添加一个输入来获取用户的文本。
HTML
<input id="inputbox" style="width: 250px;" ></input>br<br /><br />
这个输入的 id 是 inputbox,因此我们可以使用 JavaScript 获取这段文本。我在后面添加了几个断行符,以便将其间隔开。
接下来,我们将创建一个调用 JavaScript 函数的按钮:
HTML
<button type="button" onclick="GetQRCode()">Create QR Code</button>
然后我们会有一个地方,我们将插入二维码。请记住,这将是 Base64编码的,因此我们可以在 GetQRCode 函数中用图像填充这个 div。
HTML
<div id="demo"></div>
接下来,我们将放入 GetQRCode 函数,它将把一个 XMLHttpRequest 返回到 Azure 函数中并检索 JSON。然后它解析它,并用我们的映像替换“ demo”div。注意,我们添加了一个带有头信息的 img 标记,这样它就创建了一个我们可以在浏览器中查看的图像。
C#
function GetQRCode() {br var xhttp = new XMLHttpRequest();br xhttp.onreadystatechange = function () {br if (this.readyState == 4 && this.status == 200) {br var ourJSON = JSON.parse(this.responseText);br document.getElementById("demo").innerHTML = "<img src="data:image/png;base64, " + ourJSON.image + "">";br }br };br input = document.getElementById('inputbox').value xhttp.open("GET", "/api/GenerateQRCode?qrtext=" + input, true);br xhttp.send();br} <br/script>
很好! 现在我们有了一个索引页面,它将为我们的 QRCode Generator 绘制一个小 UI。
我知道我们可以添加错误纠正/处理或使用一个库,但我想让它尽可能简单。
接下来,我们需要使用 Azure 函数来完成这个任务。
Azure 函数并不打算成为 Web 服务器。事实上,Azure 静态 Web 应用程序做得更好,但是我们尽量保持它的简单性。一个 Azure 函数来完成这个任务。
我们可以推出 index.html 文件,这样它将由浏览器提供。这为我们的应用程序提供了一个小的界面,我们可以稍后回过头来构建一个完整的 Web 应用程序,利用这个功能,或者将其添加到一个微服务包中(如果愿意的话)。
再次打开 generateqrcode.cs ,在类的顶部(在[ FunctionName (“ Form”)]上)添加另一个函数。
我们希望这个函数这次返回一个 HttpResponseMessage。我们仍将使用匿名身份验证将其设置为 HttpTrigger,并传入与前面相同的值。
但是这一次,我们需要传递 ExectionContext 上下文。这为我们提供了执行上下文,这样我们就可以在本地文件系统中定位文件,稍后我将解释其中的原因。
另一个是这将返回 HttpResponseMessage 而不是 IActionResult。
C# C #
[FunctionName("Form")] brpublic static HttpResponseMessage Form([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] br HttpRequest req, ILogger log, ExecutionContext context){
接下来,我们将打开放在 www 文件夹中的 index.html 文件,并将其全部作为文本读入。这就是执行上下文的来源。
我们希望打开运行应用程序的文件系统的 www 文件夹中的 index.html 文件。我们用这行代码来实现:
C#
string indexPage = File.ReadAllText(context.FunctionAppDirectory + "/www/index.html");
然后,我们将创建一个状态代码为 OK (200)的新 HttpResponseMessage:
C#
var result = new HttpResponseMessage(HttpStatusCode.OK);
现在我们需要添加一些标题,并用我们从索引文件中读取的文本填充“内容”:
C#
result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");brresult.Content = new ByteArrayContent(System.Text.Encoding.UTF8.GetBytes(indexPage));
现在我们有了一个带有 text/html 头的200 OK 消息,并且我们已经将来自 index.html 的所有文本添加到了头的内容部分。
很俗气,但很管用。
然后我们就把它还回去:
C#
return result;
所以整个函数看起来是这样的:
C#
[FunctionName("Form")]brpublic static HttpResponseMessage Form(br [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,br ILogger log, ExecutionContext context)br{brbr string indexPage = File.ReadAllText(context.FunctionAppDirectory + "/www/index.html");brbr var result = new HttpResponseMessage(HttpStatusCode.OK);brbr result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
因为我们要引入这个需要包含在构建中的外部文件(index.html) ,所以需要将它添加到我们的。Csproj 文件。在 ItemGroup 中,添加以下代码:
HTML
<None Update="wwwindex.html">br <CopyToOutputDirectory>Always</CopyToOutputDirectory>
我在其他文件发布设置中添加了我的:
保存它,让我们再次在本地运行 Azure 函数:
Shell
func start
让我们看看它是如何工作的。
现在我已经在本地启动并运行了我的函数,所以我可以打开一个网页浏览器:
http://localhost:7071/api/Form
这就是它所有的荣耀:
我会输入一个网址,
这是我的二维码,临时生成的,太棒了! !
把它部署到 Azure 上。
所以我现在称之为“应用程序”,因为它就是。我们已经超越了一个简单函数的预期功能,只是为了展示 Azure 函数的强大。我们来部署一下,看看它是如何工作的。
用 Azure CLI 输入
Shell
az login
你会通过浏览器登录到 Azure。
在你的 Azure 控制台中,创建一个新的 Azure 函数应用程序,你可以给它取任何你喜欢的名字。
选择发布为代码,并使用下面的运行时堆栈。
我会选择 Windows 和消费(无服务器)模式:
我将创建一个新的存储帐户,然后按“查看并创建”
把你的细节记下来:
现在我们需要用 Azure CLI 发布。我们将通过使用 func 命令并指定我们想要发布一个蔚蓝色的 function 应用程序的名称来做到这一点,我们将使用“-nozip”来告诉命令我们不是在部署应用程序的 zip,而是源代码。
Shell
func azure functionapp publish qrcodegen --nozip
你应该看看这样的东西,当它完成的时候。
你将需要登录到你的 Azure 门户,加载功能应用程序并选择“配置”。
然后找到 WEBSITE _ RUN _ FROM _ PACKAGE 并将值设置为0。这将允许我们的函数在已发布的文件中运行。
我们来看看!
部署之后,您应该会看到如下屏幕:
“表单”URL 将显示我们函数的用户界面:
你可以在你的网站,并创建一个二维码从它!
我们自己的二维码生成器100% 运行 Azure 函数。
如果你一直在跟进,谢谢你坚持下来!现在您有了一个很酷的项目,并且对 Azure 函数有了更好的了解。此项目的完整源代码位于此处。
提供网站服务并不是 Azure 功能的设计目的,但我希望这是一个完整的解决方案,以支持 Azure 功能。没有服务器,没有数据库,并且您不需要跟踪多个服务。
我们学习了 Azure 函数的工作原理以及它们的简单性。我们在这里写的代码不多!我们学会了如何生成二维码。NET 库,构建一个迷你应用程序并将其部署到云中。我想尽可能简单地介绍一下。如果您正在构建一个“真正的”应用程序,以下是我的建议: