Lokales Erstellen und Testen einer einfachen Azure-Funktion mit Visual Studio

Abgeschlossen

Benutzer können eine Azure-Funktion direkt im Azure-Portal schreiben, debuggen und bereitstellen. Das Schreiben von Funktionen in einer Produktions-, Staging- oder Testumgebung ist jedoch möglicherweise nicht geeignet. Beispielsweise können Sie automatisierte Komponententests für Azure Functions schreiben oder die On-Demand-Bereitstellung von Azure-Funktionen für Azure-Funktions-Apps in Azure verwenden. Darüber hinaus ziehen es viele Entwickler vor, ihre bevorzugten Code-Editoren und Entwicklungstools anstelle der vom Azure-Portal bereitgestellten Umgebung zu verwenden. Mit Visual Studio können Sie Code mithilfe von Azure Functions-Code und -Diensten in einem einzelnen Projekt entwickeln und verwalten.

Im Szenario der Onlinewebsite für Luxusuhren sind die Entwickler und Entwicklerinnen bereits mit Visual Studio 2022 vertraut. Daher entscheiden Sie sich für Visual Studio als primäre Entwicklungsumgebung zum Erstellen von Azure Functions. Darüber hinaus bietet Visual Studio eine hervorragende Umgebung, um Ihre Funktionen lokal zu testen, bevor Sie sie in Azure bereitstellen.

In dieser Lerneinheit erfahren Sie, wie Sie die in Visual Studio verfügbaren Tools zum Erstellen und Testen einer Azure-Funktion auf Ihrem lokalen Computer verwenden.

Wichtig

Dieser Artikel unterstützt Funktionen der .NET-Klassenbibliothek, die prozessintern mit der Runtime ausgeführt werden. Ihre C#-Funktionen können auch außerhalb des Prozesses ausgeführt und von der Functions-Runtime isoliert werden. Das isolierte Workerprozessmodell ist die einzige Möglichkeit, Nicht-LTS-Versionen von .NET- und .NET Framework-Apps in aktuellen Versionen der Functions-Runtime auszuführen. Weitere Informationen finden Sie unter isolierte .NET-Workerprozessfunktionen.

Ändern der Visual Studio-Installation

Als Erstes richten Sie Visual Studio mit den Web- und Cloudtools ein, die Sie für Ihre Entwicklungsumgebung benötigen.

  1. Wenn Visual Studio 2022 lokal installiert ist, öffnen Sie den Visual Studio-Installer, und wählen Sie unter Visual Studio Community 2022 die Option Ändern aus.

    Screenshot des Visual Studio-Installers mit hervorgehobener Option „Ändern“

  2. Die Seite Ändern – Visual Studio wird angezeigt.

    Screenshot: Die Registerkarte Visual Studio Community 2022-Workloads ändern mit den hervorgehobenen Optionen ASP.NET und Webentwicklung und Azure-Entwicklung

  3. Aktivieren Sie auf der Registerkarte Workloads die Kontrollkästchen für ASP.NET und Webentwicklung sowie Azure-Entwicklung, und wählen Sie anschließend Ändern aus.

  4. Wählen Sie im Dialogfeld zur Überprüfung Ja aus. Die Seite Visual Studio-Installer wird angezeigt und zeigt den Fortschritt der zu installierenden Pakete an.

Azure Functions-Toolerweiterung für Visual Studio

Azure Functions-Tools sind eine Visual Studio-Erweiterung, mit der Sie Azure Functions in Ihrer lokalen Entwicklungsumgebung erstellen, testen und bereitstellen können. Um im Handumdrehen eine neue Azure-Funktions-App zu erstellen, bietet diese Erweiterung eine Vorlage zum Erstellen und anschließenden Bereitstellen einer Funktion direkt in Azure über Visual Studio bereit.

Die Erweiterung Azure Functions und Webauftragstools ist in Visual Studio 2022 enthalten.

Azure-Funktionen-App

Eine Funktions-App hostet mindestens eine Funktion. Sie stellt die Umgebung und die Runtime für Ihren Funktionscode zur Verfügung.

Eine Funktion wird durch ein Ereignis ausgelöst und nicht direkt aus einer App aufgerufen. Sie geben den Typ des Ereignisses an, das die einzelnen Funktionen in Ihrer Azure-Funktions-App auslöst. Die verfügbaren Ereignisse sind:

  • Blobtrigger. Dieser Typ von Funktion wird ausgeführt, wenn eine Datei hochgeladen oder im Azure Blob-Speicher geändert wird.
  • Event Hub-Trigger: Ein Event Hubs-Trigger führt die Funktion aus, wenn ein Event Hub eine Nachricht empfängt.
  • Azure Cosmos DB-Trigger: Dieser Trigger wird ausgeführt, wenn ein Dokument einer Azure Cosmos DB-Datenbank hinzugefügt oder in ihr geändert wird. Mit diesem Trigger können Sie Azure Cosmos DB mit anderen Diensten integrieren. Wenn beispielsweise ein Dokument, das die Bestellung eines Kunden darstellt, einer Datenbank hinzugefügt wird, können Sie mit einem Trigger eine Kopie der Bestellung zur Bearbeitung an eine Warteschlange senden.
  • HTTP-Trigger: Ein HTTP-Trigger führt die Funktion aus, wenn eine HTTP-Anforderung in einer Web-App auftritt. Sie können dieser Trigger auch zum Antworten auf Webhooks verwenden. Ein Webhook ist ein Rückruf, der auftritt, wenn ein Element, das von einer Website gehostet wird, geändert wird. Sie können beispielsweise eine Funktion erstellen, die von einem Webhook aus einem GitHub-Repository ausgelöst wird, wenn ein Element im Repository geändert wird.
  • Warteschlangentrigger: Dieser Trigger startet die Funktion, wenn einer Azure Storage-Warteschlange ein neues Element hinzugefügt wird.
  • Service Bus-Warteschlangentrigger: Dieser Trigger führt die Funktion aus, wenn einer Azure Service Bus-Warteschlange ein neues Element hinzugefügt wird.
  • Service Bus-Thematrigger: Dieser Trigger führt die Funktion als Reaktion auf eine neue Nachricht aus, die für ein Service Bus-Thema eingeht.
  • Timertrigger: Dieses Ereignis führt die Funktion in regelmäßigen Intervallen nach einem von Ihnen definierten Zeitplan aus.

Screenshot: Verfügbare Azure Functions-Trigger mit hervorgehobenem HTTP-Trigger

In der folgenden Tabelle sind die höchsten .NET Core- bzw. .NET Framework-Versionen aufgeführt, die mit einer bestimmten Version von Functions verwendet werden können.

Version der Functions-Laufzeit In-Process Isolierter Workerprozess
Functions 4.x .NET 6.0 .NET 6.0
.NET 7.0
.NET 8.0
.NET Framework 4.8
Functions 1.x .NET Framework 4.8

Eine Azure-Funktions-App speichert Verwaltungsinformationen, Code und Protokolle in Azure Storage. Zum Speichern dieser Daten erstellen Sie ein Speicherkonto. Das Speicherkonto muss Azure Blob, Queue, Files und Table Storage unterstützen. Verwenden Sie zu diesem Zweck ein allgemeines Azure Storage-Konto. Welches Speicherkonto für die Funktion verwendet werden soll, legen Sie über das zuvor gezeigte Dialogfeld fest.

Eine Funktion kann privilegierte oder vertrauliche Vorgänge ausführen. Eine Funktion, die durch eine HTTP-Anforderung ausgelöst wird, kann öffentlich bereitgestellt werden. Möglicherweise müssen Sie die Möglichkeit, diese Funktion auszuführen, auf ausgewählte Benutzergruppen einschränken. Sie schützen eine Funktion, indem Sie die Zugriffsrechte angeben, die zum Auslösen der Funktion erforderlich sind. Eine Funktion, die durch eine HTTP-Anforderung ausgelöst wird, unterstützt drei Ebenen von Zugriffsrechten:

  • Anonym. Es ist keine Authentifizierung erforderlich, und jeder Benutzer kann die Funktion auslösen.
  • Funktion. Die HTTP-Anforderung muss einen Schlüssel bereitstellen, der es der Azure Functions Runtime ermöglicht, die Anforderung zu autorisieren. Sie erstellen diesen Schlüssel separat. Er kann über das Azure-Portal verwaltet werden.
  • Admin. Vergleichbar mit Funktion. Benutzer*innen müssen mit der HTTP-Anforderung einen Schlüssel angeben, der die Funktion auslöst. Der Unterschied besteht darin, dass der Schlüssel ein Administratorschlüssel ist. Dieser Schlüssel kann verwendet werden, um auf eine beliebige Funktion in der Funktions-App zuzugreifen. Wie den Funktionsschlüssel erstellen Sie auch diesen Schlüssel separat.

Wenn Sie eine Funktion erstellen, die durch andere Ereignisse als HTTP-Anforderungen ausgelöst wird, müssen Sie eine Verbindungszeichenfolge und andere Details angeben, die für die Funktions-App erforderlich sind, um auf die Ressource zuzugreifen, die das Ereignis auslöst. Wenn Sie beispielsweise eine Funktion schreiben, die durch ein Blob Storage-Ereignis ausgelöst wird, müssen Sie die Verbindungszeichenfolge für das entsprechende Blob Storage-Konto angeben.

Struktur einer Azure-Funktion

Eine Azure-Funktion wird als eine statische Klasse implementiert. Die Klasse stellt eine statische, asynchrone Methode namens Run bereit, die als Einstiegspunkt für die Klasse fungiert.

Die an die Run-Methode übergebenen Parameter stellen den Kontext für den Trigger bereit. Bei einem HTTP-Trigger empfängt die Funktion ein HttpRequest-Objekt. Dieses Objekt enthält den Header und den Text der Anforderung. Sie können auf die Daten in der Anforderung mit den gleichen Techniken zugreifen, die in jeder HTTP-App verfügbar sind. Die auf diese Funktion angewendeten Attribute geben die Autorisierungsanforderungen (in diesem Fall Anonym) und die HTTP-Vorgänge an, auf die die Funktion reagiert (GET und POST).

Das folgende von Visual Studio generierte Codebeispiel untersucht die Abfragezeichenfolge, die als Teil der URL für die Anforderung angegeben wird, und sucht nach dem Parameter name. Der Code verwendet auch einen StreamReader, um den Text der Anforderung zu deserialisieren, und versucht, den Wert einer Eigenschaft, die ebenfalls name genannt wird, aus der Anforderung zu lesen. Wenn der Name in der Abfragezeichenfolge oder im Text der Anforderung gefunden wird, wird der Wert von name in der Antwort zurückgegeben. Andernfalls generiert die Funktion eine Fehlerantwort mit folgender Nachricht: Übergeben Sie einen Namen in der Abfragezeichenfolge oder dem Anforderungstext.

public static class Function1
{
    [FunctionName("Function1")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        string name = req.Query["name"];

        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        name = name ?? data?.name;

        return name != null
            ? (ActionResult)new OkObjectResult($"Hello, {name}")
            : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
    }
}

Die Funktion gibt einen Wert mit allen Ausgabedaten und Ergebnissen zurück, umschlossen in einem IAsynResult-Objekt. Der Wert wird im Text der HTTP-Antwort auf die Anforderung zurückgegeben.

Verschiedene Typen von Triggern empfangen unterschiedliche Eingabeparameter und Rückgabetypen. Das nächste Beispiel zeigt den Code, der für einen Blobtrigger generiert wird. In diesem Beispiel wird der Inhalt des Blobs über ein Stream-Objekt zurückgegeben, und der Name des Blobs wird ebenfalls angegeben. Der Trigger gibt keine Daten zurück. Er dient zum Lesen und Verarbeiten der Daten im benannten Blob.

public static class Function2
{
    [FunctionName("Function2")]
    public static void Run([BlobTrigger("samples-workitems/{name}", Connection = "xxxxxxxxxxxxxxxxxxxxxxx")]Stream myBlob, string name, ILogger log)
    {
        log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
    }
}

In allen Fällen wird ein ILogger-Parameter an eine Funktion übergeben. Die Funktion kann mit diesem Parameter Protokollnachrichten schreiben, die die Funktions-App für eine spätere Analyse in den Speicher schreibt.

Eine Funktion enthält auch Metadaten, die den Typ des Triggers, die Sicherheitsanforderungen und alle anderen spezifischen Anforderungen angeben. Sie können diese Metadaten mithilfe von HttpTrigger, BlobTrigger oder anderen Triggerattributen ändern, wie in den Beispielen gezeigt. Das Attribut FunctionName, das der Funktion vorangestellt ist, ist ein Bezeichner für die von der Funktions-App verwendete Funktion. Dieser Name muss nicht mit dem Namen der Funktion übereinstimmen, aber es ist eine bewährte Methode, diese Namen synchron zu halten, um Verwirrung zu vermeiden.

Lokales Testen einer Azure-Funktions-App

Mit dem Visual Studio-Debugger können Sie die Azure-Funktions-App lokal erstellen und testen. Drücken Sie zum Starten des Debuggers F5, oder wählen Sie Debuggen starten im Menü Debuggen aus. Die lokale Version der Functions-Runtime wird gestartet. Ihre Funktionen stehen zum Testen zur Verfügung. Das Beispiel zeigt Function1 für das Laufzeithosting, die durch ein HTTP-Ereignis ausgelöste wird. Die URL gibt den Endpunkt an, an den die Funktion zurzeit angefügt ist.

Screenshot der Azure Functions-Runtime – Beispiel 1

Wenn Sie einen Webbrowser öffnen und diese URL aufrufen, lösen Sie die Funktion aus. Die folgende Abbildung zeigt die Antwort, die durch eine HTTP GET-Anforderung generiert wird, die keinen Text enthält. Sie können die Nachricht sehen, die durch den Code generiert wird, der das BadRequestObjectResult-Objekt aus der Funktion zurückgibt.

Screenshot der Azure Functions-Runtime

Wenn Sie eine Abfragezeichenfolge angeben, die den name-Parameter enthält, wird der Wert von der Funktion gelesen und verarbeitet.

Screenshot der Azure Functions-Runtime – Beispiel 2

Während der Codeausführung werden im Fenster „Functions-Runtime“ Ablaufverfolgungsmeldungen angezeigt. Sie können Standarddebugfeatures in Visual Studio verwenden, wenn Sie Breakpoints festlegen und den Steuerungsfluss in einer Funktion untersuchen müssen.