C#-klassenbibliotheekfuncties ontwikkelen met behulp van Azure Functions

Dit artikel is een inleiding tot het ontwikkelen van Azure Functions met behulp van C# in .NET-klassebibliotheken. Deze klassebibliotheken worden gebruikt om in-process uit te voeren met de Functions-runtime. Uw .NET-functies kunnen ook _isolated uitvoeren vanuit de Functions-runtime, die verschillende voordelen biedt. Zie het geïsoleerde werkrolmodel voor meer informatie. Zie Verschillen tussen het procesmodel en het geïsoleerde werkrolmodel voor een uitgebreide vergelijking tussen deze twee modellen.

Belangrijk

Dit artikel biedt ondersteuning voor .NET-klassebibliotheekfuncties die in het proces worden uitgevoerd met de runtime. Uw C#-functies kunnen ook niet meer worden verwerkt en geïsoleerd van de Functions-runtime. Het geïsoleerde werkprocesmodel is de enige manier om niet-LTS-versies van .NET- en .NET Framework-apps uit te voeren in de huidige versies van de Functions-runtime. Zie .NET geïsoleerde werkprocesfuncties voor meer informatie. Voor een uitgebreide vergelijking tussen geïsoleerde werkprocessen en in-process .NET-functies, raadpleegt u Verschillen tussen proces- en isoleerproces .NET Azure Functions.

Als C#-ontwikkelaar bent u mogelijk ook geïnteresseerd in een van de volgende artikelen:

Aan de slag Concepten Begeleide training/voorbeelden

Azure Functions ondersteunt programmeertalen voor C# en C#-scripts. Als u hulp nodig hebt bij het gebruik van C# in Azure Portal, raadpleegt u de naslaginformatie voor C#-scripts (.csx).

Ondersteunde versies

Versies van de Functions-runtime ondersteunen specifieke versies van .NET. Zie het overzicht van runtimeversies van Azure Functions voor meer informatie over Functions-versies. Versieondersteuning is ook afhankelijk van of uw functies in proces of geïsoleerd werkproces worden uitgevoerd.

Notitie

Zie de huidige runtimeversie weergeven en bijwerken voor meer informatie over het wijzigen van de runtimeversie van Functions die door uw functie-app wordt gebruikt.

In de volgende tabel ziet u het hoogste niveau van .NET of .NET Framework dat kan worden gebruikt met een specifieke versie van Functions.

Runtimeversie van Functions Geïsoleerde werkrolmodel In-process model5
Functions 4.x .NET 8.0
.NET 7.01
.NET 6.02
.NET Framework 4.83
.NET 6.02
Functions 1.x4 N.v.t. .NET Framework 4.8

1 .NET 7 bereikt het einde van de officiële ondersteuning op 14 mei 2024.
2 .NET 6 bereikt het einde van de officiële ondersteuning op 12 november 2024.
3 Het buildproces vereist ook de .NET SDK. 4 Ondersteuning eindigt op versie 1.x van de Azure Functions-runtime op 14 september 2026. Zie deze ondersteuningsaankondiging voor meer informatie. Voor continue volledige ondersteuning moet u uw apps migreren naar versie 4.x.
5 Ondersteuning eindigt op het procesmodel op 10 november 2026. Zie deze ondersteuningsaankondiging voor meer informatie. Voor continue volledige ondersteuning moet u uw apps migreren naar het geïsoleerde werkrolmodel.

Voor het laatste nieuws over Azure Functions-releases, waaronder het verwijderen van specifieke oudere secundaire versies, controleert u Azure-app Service-aankondigingen.

Functions-klassebibliotheekproject

In Visual Studio maakt de Azure Functions-projectsjabloon een C#-klassebibliotheekproject met de volgende bestanden:

  • host.json: slaat configuratie-instellingen op die van invloed zijn op alle functies in het project wanneer ze lokaal of in Azure worden uitgevoerd.
  • local.settings.json: slaat app-instellingen en verbindingsreeks s op die worden gebruikt bij het lokaal uitvoeren. Dit bestand bevat geheimen en wordt niet gepubliceerd naar uw functie-app in Azure. Voeg in plaats daarvan app-instellingen toe aan uw functie-app.

Wanneer u het project bouwt, wordt er een mapstructuur gegenereerd die lijkt op het volgende voorbeeld in de builduitvoermap:

<framework.version>
 | - bin
 | - MyFirstFunction
 | | - function.json
 | - MySecondFunction
 | | - function.json
 | - host.json

Deze map wordt geïmplementeerd in uw functie-app in Azure. De bindingsextensies die vereist zijn in versie 2.x van de Functions-runtime, worden als NuGet-pakketten toegevoegd aan het project.

Belangrijk

Het buildproces maakt een function.json-bestand voor elke functie. Dit function.json bestand is niet bedoeld om rechtstreeks te worden bewerkt. U kunt de bindingsconfiguratie niet wijzigen of de functie uitschakelen door dit bestand te bewerken. Zie Functies uitschakelen voor meer informatie over het uitschakelen van een functie.

Methoden die worden herkend als functies

In een klassebibliotheek is een functie een methode met een FunctionName en een triggerkenmerk, zoals wordt weergegeven in het volgende voorbeeld:

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
    }
} 

Het FunctionName kenmerk markeert de methode als een functieinvoerpunt. De naam moet uniek zijn binnen een project, beginnen met een letter en mag alleen letters, cijfers _en -maximaal 127 tekens lang zijn. Projectsjablonen maken vaak een methode met de naam Run, maar de naam van de methode kan elke geldige C#-methodenaam zijn. In het bovenstaande voorbeeld ziet u een statische methode die wordt gebruikt, maar functies hoeven niet statisch te zijn.

Het triggerkenmerk geeft het triggertype op en koppelt invoergegevens aan een methodeparameter. De voorbeeldfunctie wordt geactiveerd door een wachtrijbericht en het wachtrijbericht wordt doorgegeven aan de methode in de myQueueItem parameter.

Parameters voor methodehandtekening

De handtekening van de methode kan andere parameters bevatten dan de parameter die wordt gebruikt met het triggerkenmerk. Hier volgen enkele van de andere parameters die u kunt opnemen:

De volgorde van parameters in de functiehandtekening maakt niet uit. U kunt bijvoorbeeld triggerparameters vóór of na andere bindingen plaatsen en u kunt de loggerparameter vóór of na trigger- of bindingsparameters plaatsen.

Uitvoerbindingen

Een functie kan nul of meerdere uitvoerbindingen hebben gedefinieerd met behulp van uitvoerparameters.

In het volgende voorbeeld wordt de voorgaande gewijzigd door een uitvoerwachtrijbinding met de naam myQueueItemCopytoe te voegen. De functie schrijft de inhoud van het bericht dat de functie activeert naar een nieuw bericht in een andere wachtrij.

public static class SimpleExampleWithOutput
{
    [FunctionName("CopyQueueMessage")]
    public static void Run(
        [QueueTrigger("myqueue-items-source")] string myQueueItem, 
        [Queue("myqueue-items-destination")] out string myQueueItemCopy,
        ILogger log)
    {
        log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}");
        myQueueItemCopy = myQueueItem;
    }
}

Waarden die zijn toegewezen aan uitvoerbindingen worden geschreven wanneer de functie wordt afgesloten. U kunt meer dan één uitvoerbinding in een functie gebruiken door simpelweg waarden toe te wijzen aan meerdere uitvoerparameters.

In de bindingsreferentieartikelen (bijvoorbeeld Opslagwachtrijen) wordt uitgelegd welke parametertypen u kunt gebruiken met trigger-, invoer- of uitvoerbindingskenmerken.

Voorbeeld van bindingexpressies

Met de volgende code wordt de naam van de wachtrij opgehaald die moet worden bewaakt vanuit een app-instelling en wordt de aanmaaktijd van het wachtrijbericht in de insertionTime parameter opgehaald.

public static class BindingExpressionsExample
{
    [FunctionName("LogQueueMessage")]
    public static void Run(
        [QueueTrigger("%queueappsetting%")] string myQueueItem,
        DateTimeOffset insertionTime,
        ILogger log)
    {
        log.LogInformation($"Message content: {myQueueItem}");
        log.LogInformation($"Created at: {insertionTime}");
    }
}

Automatisch gegenereerde function.json

Het buildproces maakt een function.json bestand in een functiemap in de buildmap. Zoals eerder vermeld, is dit bestand niet bedoeld om rechtstreeks te worden bewerkt. U kunt de bindingsconfiguratie niet wijzigen of de functie uitschakelen door dit bestand te bewerken.

Het doel van dit bestand is om informatie te verstrekken aan de schaalcontroller die moet worden gebruikt voor het schalen van beslissingen over het verbruiksabonnement. Daarom heeft het bestand alleen triggergegevens, niet invoer-/uitvoerbindingen.

Het gegenereerde function.json-bestand bevat een configurationSource eigenschap waarmee de runtime .NET-kenmerken moet gebruiken voor bindingen, in plaats van function.json configuratie. Hier volgt een voorbeeld:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "queueTrigger",
      "queueName": "%input-queue-name%",
      "name": "myQueueItem"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\FunctionApp1.dll",
  "entryPoint": "FunctionApp1.QueueTrigger.Run"
}

Microsoft.NET.Sdk.Functions

De function.json het genereren van bestanden wordt uitgevoerd door het NuGet-pakket Microsoft.NET.Sdk.Functions.

In het volgende voorbeeld ziet u de relevante onderdelen van de .csproj bestanden met verschillende doelframeworks van hetzelfde Sdk pakket:

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
</ItemGroup>

Onder de Sdk pakketafhankelijkheden vallen triggers en bindingen. Een 1.x-project verwijst naar 1.x-triggers en -bindingen, omdat deze triggers en bindingen gericht zijn op .NET Framework, terwijl 4.x-triggers en bindingen het doel .NET Core hebben.

Het Sdk pakket is ook afhankelijk van Newtonsoft.Json en indirect op WindowsAzure.Storage. Deze afhankelijkheden zorgen ervoor dat uw project gebruikmaakt van de versies van die pakketten die werken met de Functions Runtime-versie waarop het project is gericht. Heeft bijvoorbeeld Newtonsoft.Json versie 11 voor .NET Framework 4.6.1, maar de Functions-runtime die is gericht op .NET Framework 4.6.1 is alleen compatibel met Newtonsoft.Json 9.0.1. Uw functiecode in dat project moet dus ook 9.0.1 gebruiken Newtonsoft.Json .

De broncode Microsoft.NET.Sdk.Functions is beschikbaar in de GitHub-opslagplaats azure-functions-vs-build-sdk.

Lokale runtimeversie

Visual Studio gebruikt de Azure Functions Core Tools om Functions-projecten uit te voeren op uw lokale computer. Core Tools is een opdrachtregelinterface voor de Functions-runtime.

Als u core tools installeert met behulp van het Windows Installer-pakket (MSI) of npm, heeft dit geen invloed op de Core Tools-versie die door Visual Studio wordt gebruikt. Voor de Functions-runtimeversie 1.x slaat Visual Studio Core Tools-versies op in %USERPROFILE%\AppData\Local\Azure.Functions.Cli en wordt de meest recente versie gebruikt die daar is opgeslagen. Voor Functions 4.x zijn de Core Tools opgenomen in de extensie Azure Functions en Web Jobs Tools . Voor Functions 1.x kunt u zien welke versie wordt gebruikt in de console-uitvoer wanneer u een Functions-project uitvoert:

[3/1/2018 9:59:53 AM] Starting Host (HostId=contoso2-1518597420, Version=2.0.11353.0, ProcessId=22020, Debug=False, Attempt=0, FunctionsExtensionVersion=)

ReadyToRun

U kunt uw functie-app compileren als binaire readyToRun-bestanden. ReadyToRun is een vorm van vooraf uitgevoerde compilatie waarmee de opstartprestaties kunnen worden verbeterd om de impact van cold-start bij het uitvoeren in een verbruiksabonnement te verminderen.

ReadyToRun is beschikbaar in .NET 6 en hoger en vereist versie 4.0 van de Azure Functions-runtime.

Als u uw project wilt compileren als ReadyToRun, werkt u het projectbestand bij door de <PublishReadyToRun> en <RuntimeIdentifier> elementen toe te voegen. Hier volgt de configuratie voor het publiceren naar een Windows 32-bits functie-app.

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <PublishReadyToRun>true</PublishReadyToRun>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

Belangrijk

Vanaf .NET 6 is ondersteuning voor samengestelde ReadyToRun-compilatie toegevoegd. Bekijk de platform- en architectuurbeperkingen van ReadyToRun.

U kunt uw app ook bouwen met ReadyToRun vanaf de opdrachtregel. Zie de -p:PublishReadyToRun=true optie in dotnet publish.

Ondersteunde typen voor bindingen

Elke binding heeft zijn eigen ondersteunde typen; Een kenmerk voor een blobtrigger kan bijvoorbeeld worden toegepast op een tekenreeksparameter, een POCO-parameter, een CloudBlockBlob parameter of een van de verschillende andere ondersteunde typen. Het referentieartikel voor bindingen voor blobbindingen bevat alle ondersteunde parametertypen. Zie Triggers en bindingen en de referentiedocumenten voor bindingen voor elk bindingstype voor meer informatie.

Tip

Als u van plan bent om de HTTP- of WebHook-bindingen te gebruiken, plan dan om uitputting van de poort te voorkomen. Dat kan worden veroorzaakt door onjuiste instantie-instellingen van HttpClient. Raadpleeg Verbindingen beheren in Azure Functions voor meer informatie.

Binding naar methode retourwaarde

U kunt een retourwaarde voor een methode gebruiken voor een uitvoerbinding door het kenmerk toe te passen op de retourwaarde van de methode. Zie Triggers en bindingen voor voorbeelden.

Gebruik de retourwaarde alleen als een geslaagde functie-uitvoering altijd resulteert in een retourwaarde die moet worden doorgegeven aan de uitvoerbinding. ICollector Gebruik anders ofIAsyncCollector, zoals wordt weergegeven in de volgende sectie.

Meerdere uitvoerwaarden schrijven

Als u meerdere waarden wilt schrijven naar een uitvoerbinding, of als een geslaagde functieaanroep mogelijk niets tot gevolg heeft dat aan de uitvoerbinding wordt doorgegeven, gebruikt u de of IAsyncCollector typenICollector. Deze typen zijn alleen-schrijven verzamelingen die naar de uitvoerbinding worden geschreven wanneer de methode is voltooid.

In dit voorbeeld worden meerdere wachtrijberichten in dezelfde wachtrij geschreven met behulp van ICollector:

public static class ICollectorExample
{
    [FunctionName("CopyQueueMessageICollector")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-3")] string myQueueItem,
        [Queue("myqueue-items-destination")] ICollector<string> myDestinationQueue,
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
        myDestinationQueue.Add($"Copy 1: {myQueueItem}");
        myDestinationQueue.Add($"Copy 2: {myQueueItem}");
    }
}

Async

Als u een functie asynchroon wilt maken, gebruikt u het async trefwoord en retourneert u een Task object.

public static class AsyncExample
{
    [FunctionName("BlobCopy")]
    public static async Task RunAsync(
        [BlobTrigger("sample-images/{blobName}")] Stream blobInput,
        [Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
        CancellationToken token,
        ILogger log)
    {
        log.LogInformation($"BlobCopy function processed.");
        await blobInput.CopyToAsync(blobOutput, 4096, token);
    }
}

U kunt geen parameters in asynchrone functies gebruiken out . Voor uitvoerbindingen gebruikt u in plaats daarvan de retourwaarde van de functie of een collectorobject.

Annuleringstokens

Een functie kan een CancellationToken-parameter accepteren, waardoor het besturingssysteem uw code kan melden wanneer de functie op het punt staat te worden beëindigd. U kunt deze melding gebruiken om ervoor te zorgen dat de functie niet onverwacht wordt beëindigd op een manier die gegevens in een inconsistente status laat.

Houd rekening met het geval wanneer u een functie hebt die berichten in batches verwerkt. De volgende door Azure Service Bus geactiveerde functie verwerkt een matrix van ServiceBusReceivedMessage-objecten , die een batch binnenkomende berichten vertegenwoordigt die moeten worden verwerkt door een specifieke functieaanroep:

using Azure.Messaging.ServiceBus;
using System.Threading;

namespace ServiceBusCancellationToken
{
    public static class servicebus
    {
        [FunctionName("servicebus")]
        public static void Run([ServiceBusTrigger("csharpguitar", Connection = "SB_CONN")]
               ServiceBusReceivedMessage[] messages, CancellationToken cancellationToken, ILogger log)
        {
            try
            { 
                foreach (var message in messages)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        log.LogInformation("A cancellation token was received. Taking precautionary actions.");
                        //Take precautions like noting how far along you are with processing the batch
                        log.LogInformation("Precautionary activities --complete--.");
                        break;
                    }
                    else
                    {
                        //business logic as usual
                        log.LogInformation($"Message: {message} was processed.");
                    }
                }
            }
            catch (Exception ex)
            {
                log.LogInformation($"Something unexpected happened: {ex.Message}");
            }
        }
    }
}

Logboekregistratie

In uw functiecode kunt u uitvoer schrijven naar logboeken die worden weergegeven als traceringen in Application Insights. De aanbevolen manier om naar de logboeken te schrijven, is door een parameter van het type ILogger op te nemen, die meestal de naam logheeft. Versie 1.x van de gebruikte TraceWriterFunctions-runtime, die ook naar Application Insights schrijft, maar geen ondersteuning biedt voor gestructureerde logboekregistratie. Schrijf uw logboeken niet Console.Write , omdat deze gegevens niet worden vastgelegd door Application Insights.

ILogger

Neem in uw functiedefinitie een ILogger-parameter op, die gestructureerde logboekregistratie ondersteunt.

Met een ILogger object roept Log<level>u extensiemethoden op ILogger aan om logboeken te maken. Met de volgende code worden logboeken Information met categorie Function.<YOUR_FUNCTION_NAME>.User.geschreven:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
    logger.LogInformation("Request for item with key={itemKey}.", id);

Zie Telemetriegegevens verzamelen voor meer informatie over hoe Functions wordt geïmplementeerdILogger. Categorieën voorafgegaan door Function ervan uit te gaan dat u een ILogger exemplaar gebruikt. Als u ervoor kiest om in plaats daarvan een ILogger<T>te gebruiken, is de categorienaam mogelijk gebaseerd op T.

Gestructureerde logboekregistratie

De volgorde van tijdelijke aanduidingen, niet hun namen, bepaalt welke parameters worden gebruikt in het logboekbericht. Stel dat u de volgende code hebt:

string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);

Als u dezelfde berichttekenreeks behoudt en de volgorde van de parameters omdraait, bevat de resulterende berichttekst de waarden op de verkeerde plaatsen.

Tijdelijke aanduidingen worden op deze manier verwerkt, zodat u gestructureerde logboekregistratie kunt uitvoeren. Application Insights slaat de parameternaam-waardeparen en de berichttekenreeks op. Het resultaat is dat de berichtargumenten velden worden waarop u query's kunt uitvoeren.

Als de aanroep van de loggermethode eruitziet zoals in het vorige voorbeeld, kunt u een query uitvoeren op het veld customDimensions.prop__rowKey. Het prop__ voorvoegsel wordt toegevoegd om ervoor te zorgen dat er geen conflicten zijn tussen velden die door de runtime worden toegevoegd en velden die uw functiecode toevoegt.

U kunt ook query's uitvoeren op de oorspronkelijke berichttekenreeks door te verwijzen naar het veld customDimensions.prop__{OriginalFormat}.

Hier volgt een voorbeeld van een JSON-weergave van customDimensions gegevens:

{
  "customDimensions": {
    "prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
    "Category":"Function",
    "LogLevel":"Information",
    "prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
  }
}

Aangepaste telemetrielogboeken

Er is een functions-specifieke versie van de Application Insights SDK die u kunt gebruiken om aangepaste telemetriegegevens van uw functies te verzenden naar Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights. Gebruik de volgende opdracht vanaf de opdrachtprompt om dit pakket te installeren:

dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>

Vervang in deze opdracht door <VERSION> een versie van dit pakket die uw geïnstalleerde versie van Microsoft.Azure.WebJobs ondersteunt.

In de volgende C#-voorbeelden wordt de aangepaste telemetrie-API gebruikt. Het voorbeeld is voor een .NET-klassebibliotheek, maar de Application Insights-code is hetzelfde voor C#-script.

Versie 2.x en latere versies van de runtime gebruiken nieuwere functies in Application Insights om telemetrie automatisch te correleren met de huidige bewerking. U hoeft de bewerking Idof ParentIdName velden niet handmatig in te stellen.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System.Linq;

namespace functionapp0915
{
    public class HttpTrigger2
    {
        private readonly TelemetryClient telemetryClient;

        /// Using dependency injection will guarantee that you use the same configuration for telemetry collected automatically and manually.
        public HttpTrigger2(TelemetryConfiguration telemetryConfiguration)
        {
            this.telemetryClient = new TelemetryClient(telemetryConfiguration);
        }

        [FunctionName("HttpTrigger2")]
        public Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
            HttpRequest req, ExecutionContext context, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            DateTime start = DateTime.UtcNow;

            // Parse query parameter
            string name = req.Query
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            // Write an event to the customEvents table.
            var evt = new EventTelemetry("Function called");
            evt.Context.User.Id = name;
            this.telemetryClient.TrackEvent(evt);

            // Generate a custom metric, in this case let's use ContentLength.
            this.telemetryClient.GetMetric("contentLength").TrackValue(req.ContentLength);

            // Log a custom dependency in the dependencies table.
            var dependency = new DependencyTelemetry
            {
                Name = "GET api/planets/1/",
                Target = "swapi.co",
                Data = "https://swapi.co/api/planets/1/",
                Timestamp = start,
                Duration = DateTime.UtcNow - start,
                Success = true
            };
            dependency.Context.User.Id = name;
            this.telemetryClient.TrackDependency(dependency);

            return Task.FromResult<IActionResult>(new OkResult());
        }
    }
}

In dit voorbeeld worden de aangepaste metrische gegevens samengevoegd door de host voordat ze naar de customMetrics-tabel worden verzonden. Zie de GetMetric-documentatie in Application Insights voor meer informatie.

Wanneer u lokaal wordt uitgevoerd, moet u de APPINSIGHTS_INSTRUMENTATIONKEY instelling, met de Application Insights-sleutel, toevoegen aan het local.settings.json-bestand .

Roep niet aan TrackRequest of StartOperation<RequestTelemetry> omdat er dubbele aanvragen voor een functie-aanroep worden weergegeven. De Functions-runtime houdt automatisch aanvragen bij.

Niet instellen telemetryClient.Context.Operation.Id. Deze globale instelling veroorzaakt een onjuiste correlatie wanneer veel functies tegelijkertijd worden uitgevoerd. Maak in plaats daarvan een nieuw telemetrie-exemplaar (DependencyTelemetry, EventTelemetry) en wijzig de Context eigenschap. Geef vervolgens het telemetrie-exemplaar door aan de bijbehorende Track methode op TelemetryClient (TrackDependency(), TrackEvent(), TrackMetric()). Deze methode zorgt ervoor dat de telemetrie de juiste correlatiedetails heeft voor de huidige functie-aanroep.

Functies testen

In de volgende artikelen ziet u hoe u een C#-klassebibliotheekfunctie lokaal uitvoert voor testdoeleinden:

Omgevingsvariabelen

Als u een omgevingsvariabele of een app-instellingswaarde wilt ophalen, gebruikt System.Environment.GetEnvironmentVariableu , zoals wordt weergegeven in het volgende codevoorbeeld:

public static class EnvironmentVariablesExample
{
    [FunctionName("GetEnvironmentVariables")]
    public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
    {
        log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
        log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
    }

    private static string GetEnvironmentVariable(string name)
    {
        return name + ": " +
            System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
    }
}

App-instellingen kunnen worden gelezen uit omgevingsvariabelen, zowel bij het lokaal ontwikkelen als bij het uitvoeren in Azure. Bij het lokaal ontwikkelen zijn app-instellingen afkomstig uit de Values verzameling in het local.settings.json-bestand . In beide omgevingen, lokaal en Azure, GetEnvironmentVariable("<app setting name>") wordt de waarde van de benoemde app-instelling opgehaald. Wanneer u bijvoorbeeld lokaal werkt, wordt 'Mijn sitenaam' geretourneerd als uw local.settings.json bestand bevat { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }.

De eigenschap System.Configuration.ConfigurationManager.App Instellingen is een alternatieve API voor het ophalen van app-instellingswaarden, maar we raden u aan deze te gebruikenGetEnvironmentVariable, zoals hier wordt weergegeven.

Binding tijdens runtime

In C# en andere .NET-talen kunt u een imperatief bindingspatroon gebruiken in plaats van de declaratieve bindingen in kenmerken. Imperatieve binding is handig wanneer bindingsparameters tijdens runtime moeten worden berekend in plaats van ontwerptijd. Met dit patroon kunt u on-the-fly bindingen verbinden met ondersteunde invoer- en uitvoerbindingen in uw functiecode.

Definieer als volgt een imperatieve binding:

  • Neem geen kenmerk op in de functiehandtekening voor de gewenste imperatieve bindingen.

  • Geef een invoerparameter Binder binder of IBinder binder.

  • Gebruik het volgende C#-patroon om de gegevensbinding uit te voeren.

    using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
    {
        ...
    }
    

    BindingTypeAttribute is het .NET-kenmerk dat uw binding definieert en T een invoer- of uitvoertype is dat wordt ondersteund door dat bindingstype. T kan geen out parametertype zijn (zoals out JObject). De Mobile Apps-tabeluitvoerbinding ondersteunt bijvoorbeeld zes uitvoertypen, maar u kunt alleen ICollector<T> of IAsyncCollector<T> met imperatieve binding gebruiken.

Voorbeeld van één kenmerk

Met de volgende voorbeeldcode maakt u een storage-blobuitvoerbinding met het blobpad dat tijdens de runtime is gedefinieerd en schrijft u vervolgens een tekenreeks naar de blob.

public static class IBinderExample
{
    [FunctionName("CreateBlobUsingBinder")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-4")] string myQueueItem,
        IBinder binder,
        ILogger log)
    {
        log.LogInformation($"CreateBlobUsingBinder function processed: {myQueueItem}");
        using (var writer = binder.Bind<TextWriter>(new BlobAttribute(
                    $"samples-output/{myQueueItem}", FileAccess.Write)))
        {
            writer.Write("Hello World!");
        };
    }
}

BlobAttribute definieert de invoer- of uitvoerbinding van de opslagblob en TextWriter is een ondersteund type uitvoerbinding.

Voorbeeld van meerdere kenmerken

In het voorgaande voorbeeld wordt de app-instelling voor het hoofdopslagaccount van de functie-app verbindingsreeks (dat wil AzureWebJobsStoragewel). U kunt een aangepaste app-instelling opgeven die moet worden gebruikt voor het opslagaccount door de StorageAccountAttribute toe te voegen en de kenmerkmatrix door te geven aan BindAsync<T>(). Gebruik een Binder parameter, niet IBinder. Voorbeeld:

public static class IBinderExampleMultipleAttributes
{
    [FunctionName("CreateBlobInDifferentStorageAccount")]
    public async static Task RunAsync(
            [QueueTrigger("myqueue-items-source-binder2")] string myQueueItem,
            Binder binder,
            ILogger log)
    {
        log.LogInformation($"CreateBlobInDifferentStorageAccount function processed: {myQueueItem}");
        var attributes = new Attribute[]
        {
        new BlobAttribute($"samples-output/{myQueueItem}", FileAccess.Write),
        new StorageAccountAttribute("MyStorageAccount")
        };
        using (var writer = await binder.BindAsync<TextWriter>(attributes))
        {
            await writer.WriteAsync("Hello World!!");
        }
    }
}

Triggers en bindingen

Dit tabel geeft de bindingen weer die worden ondersteund in de belangrijkste versies van de Azure Functions-runtime:

Type 1.x1 2.x en hoger2 Activator Invoer Uitvoer
Blob Storage
Azure Cosmos DB
Azure Data Explorer
Azure SQL
Dapr4
Event Grid
Event Hubs
HTTP en webhooks
IoT Hub
Kafka3
Mobile Apps
Notification Hubs
Queue Storage
Redis
RabbitMQ3
SendGrid
Service Bus
SignalR
Table Storage
Timer
Twilio

1Ondersteuning wordt beëindigd voor versie 1.x van de Azure Functions-runtime op 14 september 2026. We raden u ten zeerste aan uw apps te migreren naar versie 4.x voor volledige ondersteuning.

2 Vanaf de runtime van versie 2.x moeten alle bindingen behalve HTTP en Timer worden geregistreerd. Raadpleeg Bindingextensies registreren.

3 Triggers worden niet ondersteund in het verbruiksabonnement. Vereist runtime-gestuurde triggers.

4 Alleen ondersteund in Kubernetes, IoT Edge en andere zelf-hostende modi.

Volgende stappen