如何建立一個有趣的二維碼項目和學習 Azure 函數
如果你想學習如何構建 Azure 函數,這里有一個有趣的項目。這個項目有點傻,但是很有教育意義。
我們將構建一個二維碼生成器,它在 Azure 函數中100% 運行。互聯網上有成千上萬的二維碼生成器,所以這是一個愚蠢的練習,但我想挑戰 Azure 函數的極限,向你展示它們是多么的酷,并激勵你用它們創建很酷的東西。
如果你更喜歡看視頻,我們這里有完整的教程:
在本教程中,你將學到:
- Azure 函數是如何工作的,它們有多簡單
- 如何使用.NET 庫生成 QR 碼
- 建造這樣的東西需要多少努力
這會很有趣的,我希望你能跟著我學習。我們將在這個教程中做什么:
- 創建 Azure 函數
- 實現一個 QR 生成器
- 為它建立一個粗糙的前沿陣地
- 使用 Azure 函數核心工具將其部署到 Azure
在本教程的最后,您將擁有一個功能性的二維碼生成器,它可能會激發您使用 Azure 函數構建更酷的東西。它們結構緊湊、簡單、易于構建。
您可以在這里找到該項目的完整源代碼。
什么是 Azure 函數?
Azure 函數是運行在 Azure 中的無服務器應用程序。它們是可以在沒有服務器或復雜實例的情況下執行的小塊代碼。大多數 Azure 函數都是“微服務”,它們完成一個小任務,并且做得很好。
Azure 函數還可以響應 HTTP 觸發器,作為一種“迷你 API”它們像 Web API 一樣響應 HTTP 請求,但是使用函數的設置要少得多。
我開始聽起來像一個廣告,但它是令人敬畏的。幾年前,這個項目要求您在某個 IIS 服務器上設置服務器或 ASP.NET Web API。現在我們只需要幾行代碼就可以做到這一點,并將其推送到云端。Azure 函數允許你專注于構建很酷的東西,而不是所有的設置。
規定
以下是本教程所需的內容。我將在 windows11中構建它,但我們不使用 VisualStudio。我將使用這個 dotnet 驅動程序,所以您可以在 mac 或 OSX 上復制它,如果您愿意的話。你必須在你的機器上安裝這個(免費的)軟件。
你需要:
- 微軟 Azure Account 帳戶
- .NET 6
- Azure Functions Core Tools
- Azure CLI Tools Azure CLI
- Visual Studio Code VisualStudio
我們開始吧!
創建新項目
我們將使用 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 命令中傳遞該值,然后返回一個二維碼。讓我們從生成二維碼開始。
安裝 QRCode 生成工具
將文本轉換成二維碼是相對復雜的。幸運的是,你在吸毒。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 碼生成工具,讓它在函數中工作吧。
創建 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
接下來,我們需要獲取字符串,將其編碼為二維碼,然后將其導出為 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 并發送出去!
創建 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”:
所以步驟很簡單:
- 發送一個 GET 到我們的 URL
- 追加要生成的文本并將其添加到 qrtext
- 接受 JSON
這是我們目前輸入的所有代碼:
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 函數來完成這個任務。
提供index.html
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。這將允許我們的函數在已發布的文件中運行。
我們來看看!
在 Azure 上運行應用程序
部署之后,您應該會看到如下屏幕:
“表單”URL 將顯示我們函數的用戶界面:
你可以在你的網站,并創建一個二維碼從它!
我們自己的二維碼生成器100% 運行 Azure 函數。
結論
如果你一直在跟進,謝謝你堅持下來!現在您有了一個很酷的項目,并且對 Azure 函數有了更好的了解。此項目的完整源代碼位于此處。
提供網站服務并不是 Azure 功能的設計目的,但我希望這是一個完整的解決方案,以支持 Azure 功能。沒有服務器,沒有數據庫,并且您不需要跟蹤多個服務。
我們學習了 Azure 函數的工作原理以及它們的簡單性。我們在這里寫的代碼不多!我們學會了如何生成二維碼。NET 庫,構建一個迷你應用程序并將其部署到云中。我想盡可能簡單地介紹一下。如果您正在構建一個“真正的”應用程序,以下是我的建議:
- 在 Azure 靜態 Web 應用程序或類似服務上托管前端
- 檢查輸入時出錯
- 優雅的錯誤處理和日志記錄
- 將圖像推入存儲器以便以后檢索
- 設計 API,以便其他類型的應用程序也可以使用它