Как использовать функции Azure для создания генератора QR-кода

Как использовать функции Azure для создания генератора QR-кода

31 мая 2022 г.

Вот интересный проект, если вы хотите научиться создавать [функции Azure] (https://bit.ly/383UrOi). Этот проект будет немного глупым, но поучительным.


Мы создадим генератор QR-кода, который на 100 % работает в функции Azure. В Интернете есть тысячи генераторов QR-кода, так что это глупое занятие, но я хотел раздвинуть границы того, что может сделать функция Azure, показать вам, насколько они круты, и вдохновить вас на создание классных вещей с их помощью.


Если вы предпочитаете смотреть видео, у нас есть полный видеоурок здесь.


В этом уроке вы узнаете:


  • Как работают функции Azure и насколько они просты

  • Как генерировать QR-коды с библиотеками .NET

  • Как мало усилий требуется, чтобы построить что-то подобное

Это будет весело, и я надеюсь, что вы будете следовать за мной. Что мы будем делать в этом уроке:


  • Создать функцию Azure

  • Реализовать QR-генератор

  • Создайте грубый интерфейс для него

  • разверните его в Azure с помощью основных инструментов Azure Functions.

К концу этого руководства у вас будет функциональный генератор QR-кода, который может вдохновить вас на создание более интересных вещей с помощью функций Azure. Они компактны, просты и легки в изготовлении.


Вы можете найти полный [исходный код этого проекта здесь] (https://github.com/JeremyMorgan/QRCode-Generator-Azure-Function).


Что такое функция Azure?


Функции Azure — это бессерверные приложения, работающие в Azure. Это небольшие фрагменты кода, которые вы можете выполнять без сервера или сложного экземпляра. Большинство функций Azure — это «микрослужбы», которые выполняют одну небольшую задачу и делают ее хорошо.


Функции Azure также могут реагировать на триггеры HTTP, выступая в роли своего рода «мини-API». Они отвечают на HTTP-запросы так же, как веб-API, но требуют гораздо меньше настроек с помощью функций.


Я начинаю походить на рекламу, но это потрясающе. Несколько лет назад для этого же проекта требовалось настроить сервер или настроить веб-API ASP.NET где-нибудь на сервере IIS. Теперь мы можем сделать это в несколько строк кода и отправить в облако. Функции Azure позволяют вам сосредоточиться на создании интересных вещей, а не на всей этой настройке.


Требования


Вот что вам понадобится для этого урока. Я соберу это в Windows 11, но мы не используем Visual Studio. Я буду использовать для этого драйвер dotnet, так что вы можете воспроизвести его на Mac или OSX, если хотите . Это (бесплатное) программное обеспечение должно быть установлено на вашем компьютере.


Тебе понадобится:



  • [.NET 6] (https://dotnet.microsoft.com/en-us/download/visual-studio-sdks)

  • [Основные инструменты функций Azure] (https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash)

  • [Инструменты Azure CLI] (https://docs.microsoft.com/en-us/cli/azure/install-azure-cli)


Итак, приступим!


Создание нового проекта


Мы собираемся использовать Azure CLI, чтобы создать для нас новую функцию Azure, и мы будем использовать драйвер dotnet для установки программного обеспечения.


Visual Studio может автоматизировать это для нас, но такой способ дает лучшее представление о необходимых шагах и может выполняться на многих платформах.


Во-первых, мы инициализируем новую функцию. Мы будем использовать команду func для создания нового проекта с именем QRCodeGen. Мы укажем рабочую среду выполнения как «dotnet», чтобы выбрать C# в качестве используемого языка.


Запустите эту команду в папке вашего проекта или репозитория:


func init QRCodeGen --worker-runtime dotnet


Если вы посмотрите в папку, здесь не так много:



Нам все еще нужно создать функцию Azure в рамках проекта. Функции Azure имеют набор шаблонов, в зависимости от того, какой тип приложения вы создаете. Мы хотим создать триггер HTTP, функцию, которая отвечает на HTTP-запрос.


func new --template "Http Trigger" --name QRCodeGen --authlevel анонимный



Если вы используете Visual Studio Code, вы можете увидеть это сообщение:



Выберите «Да», чтобы установить расширения.


Теперь вы увидите пример функции, созданной для вас func:



Вы можете запустить его локально, если хотите попробовать. Введите:


запуск функции


Затем вы увидите запуск функции, а консоль даст вам некоторые рекомендации по использованию приложения:



Как мы видим, мы можем отправить GET или POST на http://localhost:7071/api/QRCodeGen.


Давайте загрузим его в браузере и посмотрим, что возвращает простой GET:



У нас есть сообщение, показывающее:


Эта функция, активируемая HTTP, успешно выполнена. Передайте имя в строке запроса или в тексте запроса для персонализированного ответа.


Окей круто. Давайте углубимся в код и посмотрим, что означает это сообщение.


```csharp


строка responseMessage = строка.IsNullOrEmpty(имя)


? «Эта функция, активируемая HTTP, выполнена успешно. Передайте имя в строке запроса или в теле запроса для персонализированного ответа».


: $"Здравствуйте, {имя}. Эта функция, активируемая HTTP, успешно выполнена.";


Как вы можете видеть в приведенном выше коде, он выполняет проверку значения в name. Если эта переменная пуста или равна нулю, она отобразит сообщение, которое мы только что видели.


Но как нам заполнить это значение? Через несколько строк мы видим параметр в запросе, который мы можем использовать:


```csharp


имя строки = req.Query["имя"];


Он отобразит сообщение с включенным именем, если оно заполнено. Нам нужно отправить ему URL-адрес с name в качестве параметра, например:


http://localhost:7071/api/QRCodeGen?name=Джереми


Итак, давайте попробуем это:



И вот мое сообщение. Итак, теперь мы знаем, что функция работает должным образом. Мы загружаем URL-адрес, получаем параметр и изменяем вывод.


Для простоты мы будем использовать эту модель для нашего генератора QR-кода. Мы установим наш URL-адрес для прослушивания запросов и передадим значение в команде GET, а затем вернем QR-код. Давайте начнем с создания этого QR-кода.


Установите инструменты генерации QRCode


Превратить текст в QR-код относительно сложно. К счастью, вы используете .NET. Вам не придется собирать генератор вручную. Проблема давно решена. Мы будем использовать библиотеку для создания QR-кода .PNG для нас. Нам нужно только написать код вокруг него и создать инструмент, решающий нашу проблему.


Во-первых, давайте установим пакет [QRCode Generator] (https://github.com/manuelbl/QrCodeGenerator) от Manuel BL. Мы сделаем это с помощью драйвера dotnet. Я укажу последнюю версию на момент написания статьи.


dotnet добавить пакет Net.Codecrete.QrCodeGenerator --version 2.0.1


Генератор QRCode отлично работает, но может генерировать только .svgs. Поскольку нам нужен формат .PNG (растровый) и мы хотим, чтобы он работал в нескольких средах, нам необходимо установить [пакет SkiaSharp] (https://www.nuget.org/packages/SkiaSharp/2.88.0-preview. 256):


dotnet добавить пакет SkiaSharp


SkiaSharp включает в себя возможность генерировать растровые изображения. Но вы должны скачать и добавить этот файл в свой проект:


https://github.com/manuelbl/QrCodeGenerator/blob/master/Demo-SkiaSharp/QrCodeBitmapExtensions.cs


Создайте файл с именем QrCodeBitmapExtensions.cs в папке вашего проекта и скопируйте в него содержимое этого файла. Это позволит вам работать с растровыми изображениями, в частности с файлами .PNG.


Теперь у нас есть инструменты для генерации QR-кода, поэтому давайте заставим их работать в нашей функции.


Создание функции генератора QR-кода


Если вы откроете QRCodeGen.cs, вы увидите созданную для нас функцию Azure (метод). Это будет выглядеть так:


```csharp


[ИмяФункции("QRCodeGen")]


общедоступный статический асинхронный Task Run(


[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] Запрос HttpRequest,


журнал ILogger)


log.LogInformation("Триггерная функция C# HTTP обработала запрос.");


имя строки = req.Query["имя"];


строка requestBody = ожидание нового StreamReader(req.Body).ReadToEndAsync();


динамические данные = JsonConvert.DeserializeObject (requestBody);


имя = имя ?? данные?.имя;


строка responseMessage = строка.IsNullOrEmpty(имя)


? «Эта функция, активируемая HTTP, выполнена успешно. Передайте имя в строке запроса или в теле запроса для персонализированного ответа».


: $"Здравствуйте, {имя}. Эта функция, активируемая HTTP, успешно выполнена.";


вернуть новый OkObjectResult (responseMessage);


Удалим этот метод. Единственное, что вы должны увидеть в QRCodeGen.cs, это:


```csharp


пространство имен QRCodeGen


общедоступный статический класс QRCodeGen


Далее давайте добавим новый метод для генерации QR-кодов.


Во-первых, добавьте декоратор имени. Это даст методу имя и изменит URL-адрес для доступа к нему.


```csharp


[ИмяФункции("СоздатьQRCode")]


Теперь, когда мы запустим наше приложение, URL-адрес будет таким:


http://localhost:7071/api/GenerateQRCode


Это будет URL-адрес, который мы вызываем для создания QR-кода, и мы будем вызывать его из JavaScript.


Далее создайте метод:


```csharp


общедоступная статическая асинхронная задача Generate(


[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] Запрос HttpRequest, журнал ILogger)


Мы создаем метод с именем Generate. Мы передаем некоторые параметры, чтобы сообщить приложению, что нам нужен HttpTrigger:


[HttpTrigger


И внутри этого триггера мы передаем некоторые параметры.


Мы хотим сделать нашу авторизацию анонимной, чтобы любой мог получить к ней доступ:


```csharp


AuthorizationLevel.Anonymous


Мы хотим принимать только запросы GET к этому URL-адресу, поэтому следующий параметр указывает, что:


```csharp


"получить",


Затем мы установим для нашего маршрута значение null. Если нам нужен другой URL или конкретный маршрут, мы можем указать это здесь. Для простоты оставим как есть:


```csharp


Маршрут = ноль)]


Далее мы передадим объект HttpRequest. Он будет содержать данные из входящего запроса, чтобы мы могли получить из него параметры. Когда в нашу функцию отправляется запрос GET, мы можем извлечь такие вещи, как заголовки, параметры и многое другое.


```csharp


Запрос HttpRequest


Наконец, мы передадим регистратор, чтобы мы могли регистрировать сообщения.


```csharp


Журнал ILogger


Отлично, теперь у нас есть построенный метод. Давайте заполним его.


Сбор информации из строки запроса.


Пользователь должен отправить текст, который он хочет превратить в QR-код. Обычно это URL. Мы решили заранее, чтобы все было просто. Мы просто соберем эту информацию из строки запроса, отправленной в API.


Помните, что HttpRequest мы передали в метод? Отсюда мы можем получить наш параметр запроса. Мы можем установить строковую переменную, а затем получить параметр из строки запроса:


```csharp


строка qrtext = req.Query["qrtext"];


Добавьте следующее сообщение, чтобы записать наш вывод. Мы хотим отобразить то, что было отправлено в нашу переменную qrtext:


```csharp


log.LogInformation("Создание QR-кода для {0}", qrtext);


Таким образом, мы можем перепроверить то, что было отправлено.


Теперь давайте сгенерируем наш QR-код.


Генерация QR-кода в PNG


Затем мы хотим взять нашу строку, закодировать ее в QR-код, а затем экспортировать в PNG.


Итак, мы сделаем статический вызов [библиотеки QRCode] (https://github.com/manuelbl/QrCodeGenerator), которую мы установили ранее. Мы передадим текст, который хотим сгенерировать, и значение исправление ошибок. Среда должна быть в порядке.


```csharp


var qr = QrCode.EncodeText(qrtext, QrCode.Ecc.Medium);


Это все, что нужно для создания QR-кода. Но это в формате SVG. Нам нужно преобразовать его в PNG, чтобы мы могли его отобразить.


Поскольку мы добавили это растровое расширение выше, теперь наш объект qr имеет метод для преобразования QR-кода в PNG с несколькими параметрами.


Нам нужно добавить масштаб: я использовал 10, что, похоже, дало приличный размер.


Я использовал 1 для границы.


И я установил передний план (код) на SKColors.Black, а фон на SKColors.White.


Вот код для ввода:


```csharp


var pngout = qr.ToPng(10, 1, SkiaSharp.SKColors.Black, SkiaSharp.SKColors.White);


Итак, теперь у нас есть наш QR-код. Это было просто! Теперь давайте упакуем его в JSON и отправим!


Создание возвращаемого объекта JSON


Мы создали этот код в общем статическом классе GenerateQRCode. Давайте создадим еще один класс, который создаст простой объект, который мы можем вернуть при вызове API.


Сразу за пределами класса GenerateQRCode (перед последним }) создайте класс ReturnObject.


Этот класс будет иметь одно свойство с именем Image. Это будет строка, и мы закодируем в нее наш PNG как текст.


```csharp


открытый класс ReturnObject {


общедоступная строка изображения {получить; установлен; }


Теперь вернемся к классу GenerateQRCode, давайте вернемся туда, где мы были. Мы создадим новый ReturnObject:


```csharp


var ourResult = новый ReturnObject{};


Теперь мы возьмем наше изображение PNG, преобразуем его в строку Base64 и добавим эту строку в наш возвращаемый объект:


``` csharp


нашРезультат.Изображение = Convert.ToBase64String(pngout);


Легкий. Теперь мы просто вернем наш POCO (обычный старый объект класса) как новый JsonResult, поэтому он возвращает JSON вызывающей стороне:


```csharp


вернуть новый JsonResult (наш результат);


Вот и все. Примерно в семи строках кода мы берем строку, преобразуем ее в QR-код и отправляем за дверь.


Давайте попробуем.


Локальный запуск функции


Мы запустим функцию и будем прослушивать ее локально. Мы отправим запрос GET с запросом, чтобы проверить его.


Введите в командной строке следующее:


запуск функции


Для запуска функции.


Вы должны увидеть что-то вроде этого:



Теперь мы отправим запрос на


http://localhost:7071/api/GenerateQRCode


Помните, что параметр, который мы указали в нашем коде, был qrtext, поэтому я добавлю его в конец:


http://localhost:7071/api/GenerateQRCode?qrtext="привет, мир"


Я использую для этого Postman, поэтому я могу видеть, что JSON отображается:



И часть записи, которую мы сделали, показывает, что это рендеринг для «hello world»:



Итак, шаги просты:


  • Отправьте GET на наш URL

  • Добавьте текст для генерации и добавьте его в qrtext

  • Примите JSON.

Вот весь код, который мы ввели до сих пор:


```csharp


общедоступный статический класс QRCodeGen


[ИмяФункции("СоздатьQRCode")]


общедоступная статическая асинхронная задача GenerateQRCode(


[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] Запрос HttpRequest, журнал ILogger)


строка qrtext = req.Query["qrtext"];


log.LogInformation("Создание QR-кода для {0}", qrtext);


var qr = QrCode.EncodeText(qrtext, QrCode.Ecc.Medium);


var pngout = qr.ToPng(10, 1, SkiaSharp.SKColors.Black, SkiaSharp.SKColors.White);


var ourResult = новый ReturnObject{};


нашРезультат.Изображение = Convert.ToBase64String(pngout);


вернуть новый JsonResult (наш результат);


открытый класс ReturnObject {


общедоступная строка изображения {получить; установлен; }


И это фантастика, но мы еще не закончили. Нам еще нужно его развернуть. Но прежде чем мы это сделаем, давайте создадим небольшой простой интерфейс JavaScript для взаимодействия с этой функцией.


Создание внешнего интерфейса


Мы хотим, чтобы этот генератор QR-кода был полностью автономным. Хотя функции Azure на самом деле не предназначены для обслуживания веб-страниц, это возможно. В этом случае мы можем настроить это, чтобы нам не нужно было размещать наш внешний интерфейс где-то еще. Это всего лишь простая веб-страница, так что давайте ее обслужим.


Во-первых, мы создадим наш index.html.


Создайте папку с именем www и создайте файл с именем index.html.


Это будет очень простой, грубый интерфейс — ничего особенного, достаточно, чтобы выполнить работу.


Добавьте сверху следующее:




<тело>


Генератор QR-кода


Это наш основной заголовок. Далее нам нужно добавить ввод для получения текста от пользователя.






Этот ввод имеет идентификатор поля ввода, поэтому мы можем получить этот текст с помощью JavaScript. Я добавил пару разрывов строк после него, чтобы разделить его.


Далее мы создадим кнопку, которая будет вызывать функцию JavaScript:



Тогда у нас будет место, куда мы вставим QR-код. Помните, что это будет кодировка Base64, чтобы мы могли заполнить этот div изображением в нашей функции GetQRCode.



Затем мы добавим функцию GetQRCode, которая возвращает XMLHttpRequest в нашу функцию Azure и извлекает JSON. Затем он анализирует его и заменяет «демонстрационный» div нашим изображением. Обратите внимание, что мы добавляем тег img с информацией заголовка, чтобы создать изображение, которое мы можем просмотреть в нашем браузере.


функция GetQRCode () {


var xhttp = новый XMLHttpRequest();


xhttp.onreadystatechange = функция () {


если (this.readyState == 4 && this.status == 200) {


var ourJSON = JSON.parse(this.responseText);


document.getElementById("demo").innerHTML = "";


ввод = документ.getElementById('поле ввода').значение


xhttp.open("GET", "/api/GenerateQRCode?qrtext=" + input, true);


хhttp.отправить();



Большой! Итак, теперь у нас есть индексная страница, которая будет отображать небольшой пользовательский интерфейс для нашего генератора QRCode.


Я знаю, что мы могли бы добавить исправление/обработку ошибок или использовать для этого библиотеку, но я хочу, чтобы это было как можно проще.


Затем нам нужно обслужить это с помощью нашей функции Azure.


Обслуживание индексной страницы


Функции Azure не предназначены для использования в качестве веб-серверов. На самом деле, [статические веб-приложения Azure] (https://azure.microsoft.com/en-us/services/app-service/static/) работают намного лучше, но мы пытаемся сделать это максимально простым. может быть. Одна единственная функция Azure для выполнения этой задачи.


Мы можем вытолкнуть файл index.html, чтобы он обслуживался браузером. Это дает небольшой интерфейс для нашего приложения, и мы можем вернуться позже и создать полное веб-приложение, использующее преимущества этой функции, или добавить его в набор микросервисов, если захотим.


Снова откройте GenerateQRCode.cs и в верхней части нашего класса (выше [FunctionName("Form")]) давайте добавим еще одну функцию.


Мы хотим, чтобы на этот раз эта функция возвращала HttpResponseMessage. Мы по-прежнему собираемся сделать это HttpTrigger с анонимной аутентификацией и передавать те же значения, что и раньше.


Однако на этот раз нам нужно передать ExecutionContext context. Это дает нам наш контекст выполнения, чтобы мы могли найти файлы в локальной файловой системе, и я немного объясню почему.


Во-вторых, это вернет HttpResponseMessage вместо IActionResult.


[ИмяФункции("Форма")]


общедоступная статическая форма HttpResponseMessage (


[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] Запрос HttpRequest,


Журнал ILogger, контекст ExecutionContext)


Затем мы собираемся открыть файл index.html, который мы поместили в папку www, и прочитать его весь как текст. Вот откуда берется контекст выполнения.


Мы хотим открыть файл index.html, который находится в папке www в файловой системе, где запущено приложение. Мы делаем это с помощью этой строки кода:


```csharp


string indexPage = File.ReadAllText(context.FunctionAppDirectory + "/www/index.html");


Затем мы создадим новый HttpResponseMessage с кодом состояния OK (200):


```csharp


результат var = новое HttpResponseMessage(HttpStatusCode.OK);


Теперь нам нужно добавить к этому некоторые заголовки и заполнить «контент» текстом, который мы прочитали из нашего индексного файла:


```csharp


result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");


result.Content = new ByteArrayContent (System.Text.Encoding.UTF8.GetBytes (indexPage));


Теперь у нас есть сообщение 200 OK с заголовком text/html, и весь текст из нашего index.html добавлен в раздел контента заголовка.


Это довольно хакерски, но это работает.


Затем мы просто возвращаем его:


```csharp


вернуть результат;


Итак, вся функция выглядит так:


```csharp


[ИмяФункции("Форма")]


общедоступная статическая форма HttpResponseMessage (


[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] Запрос HttpRequest,


Журнал ILogger, контекст ExecutionContext)


string indexPage = File.ReadAllText(context.FunctionAppDirectory + "/www/index.html");


результат var = новое HttpResponseMessage(HttpStatusCode.OK);


result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");


result.Content = new ByteArrayContent (System.Text.Encoding.UTF8.GetBytes (indexPage));


вернуть результат;


Теперь, поскольку мы представляем этот внешний файл (index.html), который нужно будет включить в сборку, нам нужно добавить его в наш файл .csproj. В ItemGroup добавьте следующий код:


```xml


<Нет Обновить="www\index.html">


Всегда



Я добавил свой с другими настройками публикации файлов:



Сохраните его и давайте снова запустим нашу функцию Azure локально:


запуск функции


И давайте посмотрим, как это работает.


Тестирование нашего внешнего интерфейса


Теперь моя функция запущена и работает локально, поэтому я могу просто запустить веб-браузер, чтобы:


http://локальный: 7071/апи/форма


а вот он во всей красе:



Итак, я добавлю URL:



И вот мой QR-код, временно сгенерированный. Потрясающий!!


Давайте развернем это в Azure.


Развертывание нашего приложения


Наш проект теперь по сути приложение. Мы вышли за пределы ожидаемой функциональности простой функции, просто чтобы показать, насколько мощными могут быть Функции Azure. Давайте развернем это и посмотрим, как это работает.


В Azure CLI введите


логин az


Через веб-браузер вам будет предложено войти в Azure.



В консоли Azure создайте новое приложение-функцию Azure. Вы можете назвать это как хотите.



Выберите, чтобы опубликовать как код и использовать следующий стек среды выполнения. Вы можете выбрать любой регион, который вам нравится.



Я выберу Windows и модель потребления (без сервера):



Я создам новую учетную запись хранения и нажму «Просмотреть и создать».



Запишите свои данные:



Теперь нам нужно опубликовать с помощью Azure CLI. Мы сделаем это, используя команду func и указав, что мы хотим опубликовать azure functionapp, имя, и мы поместим "--nozip", чтобы сообщить команде, что мы не развертываем zip-архив приложения. , а скорее исходный код.


func azure functionapp опубликовать qrcodegen --nozip


Вы должны увидеть что-то подобное, когда это будет сделано.



Вам нужно будет войти на портал Azure, загрузить функциональное приложение и выбрать «Конфигурация».



Затем найдите «WEBSITE_RUN_FROM_PACKAGE» и установите значение «0». Это позволит нашей функции запускаться из файлов, которые мы опубликовали.



Давайте взглянем!


Запуск приложения в Azure


После развертывания вы должны увидеть такой экран:



URL-адрес «Формы» — это тот, который вызовет наш пользовательский интерфейс для функции:



И вы можете ввести свой веб-сайт и создать из него QR-код!



И это работает!! Наш собственный генератор QR-кода, работающий на 100 % из функции Azure.


Вывод


Если вы следили за новостями, спасибо, что не пропустили! Теперь у вас есть отличный проект и вы лучше знакомы с функциями Azure. Обслуживание веб-сайтов — это не совсем то, для чего предназначены функции Azure, но я хотел, чтобы это было комплексное решение для функции Azure. Никаких серверов, никаких баз данных, и у вас нет нескольких служб, за которыми нужно следить.


Мы узнали, как работают функции Azure и насколько простыми они могут быть. Мы не написали здесь много кода! Мы научились генерировать QR-коды с помощью .NET-библиотек, создавать мини-приложение и развертывать его в облаке. Я хотел, чтобы это было как можно проще для хорошего введения. Если бы вы создавали «настоящее» приложение, я бы порекомендовал следующее:


  • Размещение внешнего интерфейса в Статических веб-приложениях Azure или аналогичной службе.

  • Ошибка при проверке ввода

  • Изящная обработка ошибок и ведение журнала

  • Отправка изображений в хранилище для последующего извлечения

  • Разработка API таким образом, чтобы его можно было использовать и в других типах приложений.

Надеюсь, это было весело! Если вы хотите узнать больше о функциях Azure, доступно несколько различных курсов:





Снова вот видеоверсия этого руководства. Если у вас есть какие-либо вопросы или комментарии, дайте мне знать в комментариях!


Также опубликовано [здесь] (https://www.allhandsontech.com/programming/dotnet/how-to-qr-code-generator-azure-functions/)



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE