Utveckla C#-klassbiblioteksfunktioner med hjälp av Azure Functions
Viktigt!
Supporten upphör för den pågående modellen den 10 november 2026. Vi rekommenderar starkt att du migrerar dina appar till den isolerade arbetsmodellen för fullt stöd.
Den här artikeln är en introduktion till att utveckla Azure Functions med hjälp av C# i .NET-klassbibliotek. Dessa klassbibliotek används för att köras i processen med Functions-körningen. Dina .NET-funktioner kan också köra _isolated från Functions-körningen, vilket ger flera fördelar. Mer information finns i den isolerade arbetsmodellen. En omfattande jämförelse mellan dessa två modeller finns i Skillnader mellan den processbaserade modellen och den isolerade arbetsmodellen.
Viktigt!
Den här artikeln stöder .NET-klassbiblioteksfunktioner som körs i processen med körningen. C#-funktionerna kan också köras utan process och isoleras från Functions-körningen. Den isolerade arbetsprocessmodellen är det enda sättet att köra icke-LTS-versioner av .NET- och .NET Framework-appar i aktuella versioner av Functions-körningen. Mer information finns i .NET-isolerade arbetsprocessfunktioner. En omfattande jämförelse mellan isolerade arbetsprocesser och processer i .NET Functions finns i Skillnader mellan processer och isolera arbetsprocess .NET Azure Functions.
Som C#-utvecklare kan du också vara intresserad av någon av följande artiklar:
Komma igång | Begrepp | Guidad utbildning/exempel |
---|---|---|
Azure Functions har stöd för programmeringsspråk för C# och C#-skript. Om du vill ha vägledning om hur du använder C# i Azure Portal läser du utvecklarreferensen för C#-skript (.csx).
Versioner som stöds
Versioner av Functions-körningen stöder specifika versioner av .NET. Mer information om Functions-versioner finns i Översikt över Azure Functions-körningsversioner. Versionsstöd beror också på om dina funktioner körs i en process eller en isolerad arbetsprocess.
Kommentar
Information om hur du ändrar den Functions-körningsversion som används av funktionsappen finns i Visa och uppdatera den aktuella körningsversionen.
I följande tabell visas den högsta nivån av .NET eller .NET Framework som kan användas med en specifik version av Functions.
Funktionskörningsversion | Isolerad arbetsmodell | Processmodell5 |
---|---|---|
Funktioner 4.x1 | .NET 9.0 (förhandsversion) .NET 8.0 .NET 6.02 .NET Framework 4.83 |
.NET 8.0 .NET 6.02 |
Funktioner 1.x4 | saknas | .NET Framework 4.8 |
1 .NET 7 hade tidigare stöd för den isolerade arbetsmodellen men nådde slutet av det officiella stödet den 14 maj 2024.
2 .NET 6 når slutet av det officiella stödet den 12 november 2024.
3 Byggprocessen kräver också .NET SDK.
4 Support upphör för version 1.x av Azure Functions-körningen den 14 september 2026. Mer information finns i det här supportmeddelandet. Om du vill ha fortsatt fullständigt stöd bör du migrera dina appar till version 4.x.
5 Supporten upphör för den pågående modellen den 10 november 2026. Mer information finns i det här supportmeddelandet. Om du vill ha fortsatt fullständigt stöd bör du migrera dina appar till den isolerade arbetsmodellen.
För de senaste nyheterna om Azure Functions-versioner, inklusive borttagning av specifika äldre mindre versioner, övervakar du Azure App Service-meddelanden.
Uppdatera till målet .NET 8
Appar som använder den processbaserade modellen kan rikta in sig på .NET 8 genom att följa stegen som beskrivs i det här avsnittet. Men om du väljer att använda det här alternativet bör du fortfarande börja planera migreringen till den isolerade arbetsmodellen innan supporten upphör för den pågående modellen den 10 november 2026.
Många appar kan ändra konfigurationen av funktionsappen i Azure utan uppdateringar av kod eller omdistribution. För att köra .NET 8 med den processbaserade modellen krävs tre konfigurationer:
- Programinställningen
FUNCTIONS_WORKER_RUNTIME
måste anges med värdet "dotnet". - Programinställningen
FUNCTIONS_EXTENSION_VERSION
måste anges med värdet "~4". - Programinställningen
FUNCTIONS_INPROC_NET8_ENABLED
måste anges med värdet "1". - Du måste uppdatera stackkonfigurationen för att referera till .NET 8.
Stöd för .NET 8 använder fortfarande version 4.x av Functions-körningen och ingen ändring av den konfigurerade körningsversionen krävs.
Om du vill uppdatera ditt lokala projekt kontrollerar du först att du använder de senaste versionerna av lokala verktyg. Kontrollera sedan att projektet refererar till version 4.4.0 eller senare av Microsoft.NET.Sdk.Functions. Du kan sedan ändra TargetFramework
till "net8.0". Du måste också uppdatera local.settings.json
för att inkludera både FUNCTIONS_WORKER_RUNTIME
inställt på "dotnet" och FUNCTIONS_INPROC_NET8_ENABLED
inställt på "1".
Följande är ett exempel på en minimal project
fil med dessa ändringar:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
Följande är ett exempel på en minimal local.settings.json
fil med dessa ändringar:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_INPROC_NET8_ENABLED": "1",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
Om din app använder Microsoft.Azure.DurableTask.Netherite.AzureFunctions
kontrollerar du att den är riktad mot version 1.5.3 eller senare. På grund av en beteendeförändring i .NET 8 utlöser appar med äldre versioner av paketet ett tvetydigt konstruktorfel.
Du kan behöva göra andra ändringar i din app baserat på versionsstöd för dess andra beroenden.
Version 4.x av Functions-körningen ger motsvarande funktioner för .NET 6 och .NET 8. Den processbaserade modellen innehåller inte ytterligare funktioner eller uppdateringar som integreras med nya .NET 8-funktioner. Körningen stöder till exempel inte nyckelade tjänster. Om du vill dra full nytta av de senaste .NET 8-funktionerna och förbättringarna måste du migrera till den isolerade arbetsmodellen.
Projekt för functions-klassbibliotek
I Visual Studio skapar Azure Functions-projektmallen ett C#-klassbiblioteksprojekt som innehåller följande filer:
- host.json – lagrar konfigurationsinställningar som påverkar alla funktioner i projektet när de körs lokalt eller i Azure.
- local.settings.json – lagrar appinställningar och anslutningssträng som används när de körs lokalt. Den här filen innehåller hemligheter och publiceras inte till din funktionsapp i Azure. Lägg i stället till appinställningar i funktionsappen.
När du skapar projektet genereras en mappstruktur som ser ut som i följande exempel i utdatakatalogen för bygget:
<framework.version>
| - bin
| - MyFirstFunction
| | - function.json
| - MySecondFunction
| | - function.json
| - host.json
Den här katalogen är det som distribueras till din funktionsapp i Azure. Bindningstilläggen som krävs i version 2.x av Functions-körningen läggs till i projektet som NuGet-paket.
Viktigt!
Byggprocessen skapar en function.json fil för varje funktion. Den här function.json filen är inte avsedd att redigeras direkt. Du kan inte ändra bindningskonfigurationen eller inaktivera funktionen genom att redigera den här filen. Information om hur du inaktiverar en funktion finns i Inaktivera funktioner.
Metoder som identifieras som funktioner
I ett klassbibliotek är en funktion en metod med ett FunctionName
och ett utlösarattribut, som du ser i följande exempel:
public static class SimpleExample
{
[FunctionName("QueueTrigger")]
public static void Run(
[QueueTrigger("myqueue-items")] string myQueueItem,
ILogger log)
{
log.LogInformation($"C# function processed: {myQueueItem}");
}
}
Attributet FunctionName
markerar metoden som en funktionsinmatningspunkt. Namnet måste vara unikt i ett projekt, börja med en bokstav och endast innehålla bokstäver, siffror, _
och -
, upp till 127 tecken långa. Projektmallar skapar ofta en metod med namnet Run
, men metodnamnet kan vara valfritt giltigt C#-metodnamn. Exemplet ovan visar en statisk metod som används, men funktioner krävs inte för att vara statiska.
Utlösarattributet anger utlösartypen och binder indata till en metodparameter. Exempelfunktionen utlöses av ett kömeddelande och kömeddelandet skickas till metoden i parametern myQueueItem
.
Parametrar för metodsignatur
Metodsignaturen kan innehålla andra parametrar än den som används med utlösarattributet. Här är några av de andra parametrarna som du kan inkludera:
- Indata- och utdatabindningar markerade som sådana genom att dekorera dem med attribut.
- En
ILogger
ellerTraceWriter
(version 1.x-only) parameter för loggning. - En
CancellationToken
parameter för graciös avstängning. - Bindningsuttrycksparametrar för att hämta utlösarmetadata.
Ordningen på parametrarna i funktionssignaturen spelar ingen roll. Du kan till exempel sätta utlösarparametrar före eller efter andra bindningar och du kan placera loggerparametern före eller efter utlösare eller bindningsparametrar.
Utdatabindningar
En funktion kan ha noll- eller flera utdatabindningar definierade med hjälp av utdataparametrar.
I följande exempel ändras föregående genom att lägga till en utdataköbindning med namnet myQueueItemCopy
. Funktionen skriver innehållet i meddelandet som utlöser funktionen till ett nytt meddelande i en annan kö.
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;
}
}
Värden som tilldelas utdatabindningar skrivs när funktionen avslutas. Du kan använda mer än en utdatabindning i en funktion genom att helt enkelt tilldela värden till flera utdataparametrar.
I referensartiklarna för bindning (t.ex. lagringsköer) förklaras vilka parametertyper du kan använda med bindningsattribut för utlösare, indata eller utdata.
Exempel på bindningsuttryck
Följande kod hämtar namnet på kön som ska övervakas från en appinställning och hämtar tiden för att skapa kömeddelanden i parametern insertionTime
.
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}");
}
}
Automatiskt genererad function.json
Byggprocessen skapar en function.json fil i en funktionsmapp i byggmappen. Som tidigare nämnts är den här filen inte avsedd att redigeras direkt. Du kan inte ändra bindningskonfigurationen eller inaktivera funktionen genom att redigera den här filen.
Syftet med den här filen är att ge information till skalningskontrollanten som ska användas för skalningsbeslut i förbrukningsplanen. Därför har filen bara utlösarinformation, inte indata-/utdatabindningar.
Den genererade function.json-filen innehåller en configurationSource
egenskap som talar om för körningen att använda .NET-attribut för bindningar i stället för function.json konfiguration. Här är ett exempel:
{
"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
Den function.json filgenereringen utförs av NuGet-paketet Microsoft.NET.Sdk.Functions.
I följande exempel visas relevanta delar av .csproj
filerna som har olika målramverk i samma Sdk
paket:
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.4.0" />
</ItemGroup>
Sdk
Bland paketberoendena finns utlösare och bindningar. Ett 1.x-projekt refererar till 1.x-utlösare och bindningar eftersom dessa utlösare och bindningar riktar sig mot .NET Framework, medan 4.x-utlösare och bindningar riktar in sig på .NET Core.
Paketet Sdk
beror också på Newtonsoft.Json och indirekt på WindowsAzure.Storage. Dessa beroenden ser till att projektet använder de versioner av paketen som fungerar med den Functions-körningsversion som projektet riktar in sig på. Har till exempel Newtonsoft.Json
version 11 för .NET Framework 4.6.1, men Functions-körningen som riktar sig mot .NET Framework 4.6.1 är endast kompatibel med Newtonsoft.Json
9.0.1. Därför måste din funktionskod i projektet också använda Newtonsoft.Json
9.0.1.
Källkoden för Microsoft.NET.Sdk.Functions
är tillgänglig i GitHub-lagringsplatsen azure-functions-vs-build-sdk.
Lokal körningsversion
Visual Studio använder Azure Functions Core Tools för att köra Functions-projekt på din lokala dator. Core Tools är ett kommandoradsgränssnitt för Functions-körningen.
Om du installerar Core Tools med windows installer-paketet (MSI) eller med hjälp av npm påverkar det inte den Core Tools-version som används av Visual Studio. För Functions-körningsversion 1.x lagrar Visual Studio Core Tools-versioner i %USERPROFILE%\AppData\Local\Azure.Functions.Cli och använder den senaste versionen som lagras där. För Functions 4.x ingår Core Tools i tillägget Azure Functions och Web Jobs Tools . För Functions 1.x kan du se vilken version som används i konsolutdata när du kör ett Functions-projekt:
[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
Du kan kompilera funktionsappen som ReadyToRun-binärfiler. ReadyToRun är en form av kompilering i förväg som kan förbättra startprestanda för att minska effekten av kallstart när du kör i en förbrukningsplan.
ReadyToRun är tillgängligt i .NET 6 och senare versioner och kräver version 4.0 av Azure Functions-körningen.
Om du vill kompilera projektet som ReadyToRun uppdaterar du projektfilen genom att lägga till elementen <PublishReadyToRun>
och <RuntimeIdentifier>
. Följande är konfigurationen för publicering till en Windows 32-bitars funktionsapp.
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<PublishReadyToRun>true</PublishReadyToRun>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>
Viktigt!
Från och med .NET 6 har stöd för sammansatt ReadyToRun-kompilering lagts till. Kolla in Begränsningar för ReadyToRun Cross-plattform och arkitektur.
Du kan också skapa din app med ReadyToRun från kommandoraden. Mer information finns i alternativet -p:PublishReadyToRun=true
i dotnet publish
.
Typer som stöds för bindningar
Varje bindning har sina egna typer som stöds. Till exempel kan ett blobutlösarattribut tillämpas på en strängparameter, en POCO-parameter, en CloudBlockBlob
parameter eller någon av flera andra typer som stöds. I artikeln med bindningsreferenser för blobbindningar visas alla parametertyper som stöds. Mer information finns i Utlösare och bindningar och bindningsreferensdokumenten för varje bindningstyp.
Dricks
Om du planerar att använda HTTP- eller WebHook-bindningarna planerar du att undvika portöverbelastning som kan orsakas av felaktig instansiering av HttpClient
. Mer information finns i Hantera anslutningar i Azure Functions.
Bindning till metodens returvärde
Du kan använda ett metodreturvärde för en utdatabindning genom att tillämpa attributet på metodens returvärde. Exempel finns i Utlösare och bindningar.
Använd endast returvärdet om en lyckad funktionskörning alltid resulterar i ett returvärde som skickas till utdatabindningen. Annars använder du ICollector
eller IAsyncCollector
, som du ser i följande avsnitt.
Skriva flera utdatavärden
Om du vill skriva flera värden till en utdatabindning, eller om ett lyckat funktionsanrop kanske inte resulterar i något att skicka till utdatabindningen, använder du typerna ICollector
eller IAsyncCollector
. Dessa typer är skrivskyddade samlingar som skrivs till utdatabindningen när metoden är klar.
Det här exemplet skriver flera kömeddelanden i samma kö med hjälp av 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}");
}
}
Asynkrona
Om du vill göra en funktion asynkron använder du nyckelordet async
och returnerar ett Task
objekt.
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);
}
}
Du kan inte använda out
parametrar i asynkrona funktioner. För utdatabindningar använder du funktionens returvärde eller ett insamlarobjekt i stället.
Annulleringstoken
En funktion kan acceptera parametern CancellationToken , vilket gör att operativsystemet kan meddela koden när funktionen är på väg att avslutas. Du kan använda det här meddelandet för att se till att funktionen inte avslutas oväntat på ett sätt som lämnar data i ett inkonsekvent tillstånd.
Tänk på fallet när du har en funktion som bearbetar meddelanden i batchar. Följande Azure Service Bus-utlösta funktion bearbetar en matris med ServiceBusReceivedMessage-objekt , som representerar en batch med inkommande meddelanden som ska bearbetas av en specifik funktionsanrop:
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}");
}
}
}
}
Loggning
I funktionskoden kan du skriva utdata till loggar som visas som spårningar i Application Insights. Det rekommenderade sättet att skriva till loggarna är att inkludera en parameter av typen ILogger, som vanligtvis heter log
. Version 1.x av functions-körningen som används TraceWriter
, som även skriver till Application Insights, men inte stöder strukturerad loggning. Använd Console.Write
inte för att skriva dina loggar eftersom dessa data inte samlas in av Application Insights.
ILogger
I funktionsdefinitionen inkluderar du en ILogger-parameter som stöder strukturerad loggning.
Med ett ILogger
objekt anropar Log<level>
du tilläggsmetoder på ILogger för att skapa loggar. Följande kod skriver Information
loggar med kategori Function.<YOUR_FUNCTION_NAME>.User.
:
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
logger.LogInformation("Request for item with key={itemKey}.", id);
Mer information om hur Functions implementerar finns ILogger
i Samla in telemetridata. Kategorier som prefixet med Function
förutsätter att du använder en ILogger
instans. Om du väljer att i stället använda ett ILogger<T>
kan kategorinamnet i stället baseras på T
.
Strukturerad loggning
Platshållarnas ordning, inte deras namn, avgör vilka parametrar som används i loggmeddelandet. Anta att du har följande kod:
string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);
Om du behåller samma meddelandesträng och ändrar ordningen på parametrarna skulle den resulterande meddelandetexten ha värdena på fel platser.
Platshållare hanteras på det här sättet så att du kan utföra strukturerad loggning. Application Insights lagrar parameterns namn/värde-par och meddelandesträngen. Resultatet är att meddelandeargumenten blir fält som du kan fråga efter.
Om loggermetodanropet ser ut som i föregående exempel kan du fråga fältet customDimensions.prop__rowKey
. Prefixet prop__
läggs till för att säkerställa att det inte finns några kollisioner mellan fält som runtime lägger till och fält som funktionskoden lägger till.
Du kan också fråga efter den ursprungliga meddelandesträngen genom att referera till fältet customDimensions.prop__{OriginalFormat}
.
Här är en JSON-exempelrepresentation av customDimensions
data:
{
"customDimensions": {
"prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
"Category":"Function",
"LogLevel":"Information",
"prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
}
}
Logga anpassad telemetri
Det finns en Funktionsspecifik version av Application Insights SDK som du kan använda för att skicka anpassade telemetridata från dina funktioner till Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights. Använd följande kommando från kommandotolken för att installera det här paketet:
dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>
I det här kommandot ersätter du <VERSION>
med en version av det här paketet som stöder din installerade version av Microsoft.Azure.WebJobs.
I följande C#-exempel används det anpassade telemetri-API:et. Exemplet är för ett .NET-klassbibliotek, men Application Insights-koden är densamma för C#-skriptet.
Version 2.x och senare versioner av körningen använder nyare funktioner i Application Insights för att automatiskt korrelera telemetri med den aktuella åtgärden. Du behöver inte ange åtgärden Id
, ParentId
eller Name
fälten manuellt.
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());
}
}
}
I det här exemplet aggregeras anpassade måttdata av värden innan de skickas till tabellen customMetrics. Mer information finns i GetMetric-dokumentationen i Application Insights.
När du kör lokalt måste du lägga till APPINSIGHTS_INSTRUMENTATIONKEY
inställningen med Application Insights-nyckeln i filen local.settings.json .
Anropa TrackRequest
inte eller StartOperation<RequestTelemetry>
för att du ser duplicerade begäranden för ett funktionsanrop. Functions-körningen spårar automatiskt begäranden.
Ställ inte in telemetryClient.Context.Operation.Id
. Den här globala inställningen orsakar felaktig korrelation när många funktioner körs samtidigt. Skapa i stället en ny telemetriinstans (DependencyTelemetry
, EventTelemetry
) och ändra dess Context
egenskap. Skicka sedan in telemetriinstansen till motsvarande Track
metod på TelemetryClient
(TrackDependency()
, TrackEvent()
, TrackMetric()
). Den här metoden säkerställer att telemetrin har rätt korrelationsinformation för den aktuella funktionsanropet.
Testa funktioner
Följande artiklar visar hur du kör en processbaserad C#-klassbiblioteksfunktion lokalt i testsyfte:
Miljövariabler
Om du vill hämta en miljövariabel eller ett appinställningsvärde använder du System.Environment.GetEnvironmentVariable
, som du ser i följande kodexempel:
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);
}
}
Appinställningar kan läsas från miljövariabler både när du utvecklar lokalt och när de körs i Azure. När du utvecklar lokalt kommer appinställningarna från Values
samlingen i local.settings.json-filen. I båda miljöerna, lokalt och Azure, GetEnvironmentVariable("<app setting name>")
hämtar värdet för den namngivna appinställningen. När du till exempel kör lokalt returneras "Mitt webbplatsnamn" om din local.settings.json fil innehåller { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }
.
Egenskapen System.Configuration.ConfigurationManager.AppSettings är ett alternativt API för att hämta appinställningsvärden , men vi rekommenderar att du använder GetEnvironmentVariable
det som visas här.
Bindning vid körning
I C# och andra .NET-språk kan du använda ett imperativt bindningsmönster, till skillnad från deklarativa bindningar i attribut. Imperativ bindning är användbart när bindningsparametrar måste beräknas vid körning i stället för designtid. Med det här mönstret kan du binda till indata- och utdatabindningar som stöds direkt i funktionskoden.
Definiera en imperativ bindning enligt följande:
Inkludera inte ett attribut i funktionssignaturen för önskade imperativa bindningar.
Skicka in en indataparameter
Binder binder
ellerIBinder binder
.Använd följande C#-mönster för att utföra databindningen.
using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...))) { ... }
BindingTypeAttribute
är .NET-attributet som definierar bindningen ochT
är en indata- eller utdatatyp som stöds av den bindningstypen.T
kan inte vara enout
parametertyp (till exempelout JObject
). Till exempel stöder mobile apps-tabellutdatabindningen sex utdatatyper, men du kan bara använda ICollector<T> eller IAsyncCollector<T> med imperativ bindning.
Exempel på enstaka attribut
I följande exempelkod skapas en storage blob-utdatabindning med blobsökvägen som definieras vid körning och skriver sedan en sträng till bloben.
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 definierar bindningen för in- eller utdata för lagringsblob och TextWriter är en utdatabindningstyp som stöds.
Exempel på flera attribut
I föregående exempel hämtas appinställningen för funktionsappens huvudlagringskonto anslutningssträng (som är AzureWebJobsStorage
). Du kan ange en anpassad appinställning som ska användas för lagringskontot genom att lägga till StorageAccountAttribute och skicka attributmatrisen till BindAsync<T>()
. Använd en Binder
parameter, inte IBinder
. Till exempel:
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!!");
}
}
}
Utlösare och bindningar
Den här tabellen visar bindningar som stöds i huvudversionerna av Azure Functions-körningen:
Typ | 1.x1 | 2.x och högre2 | Utlösare | Indata | Utdata |
---|---|---|---|---|---|
Blob Storage | ✔ | ✔ | ✔ | ✔ | ✔ |
Azure Cosmos DB | ✔ | ✔ | ✔ | ✔ | ✔ |
Azure-datautforskaren | ✔ | ✔ | ✔ | ||
Azure SQL | ✔ | ✔ | ✔ | ✔ | |
Dapr4 | ✔ | ✔ | ✔ | ✔ | |
Event Grid | ✔ | ✔ | ✔ | ✔ | |
Event Hubs | ✔ | ✔ | ✔ | ✔ | |
HTTP & webhooks | ✔ | ✔ | ✔ | ✔ | |
IoT Hub | ✔ | ✔ | ✔ | ||
Kafka3 | ✔ | ✔ | ✔ | ||
Mobile Apps | ✔ | ✔ | ✔ | ||
Notification Hubs | ✔ | ✔ | |||
Queue Storage | ✔ | ✔ | ✔ | ✔ | |
Redis | ✔ | ✔ | |||
RabbitMQ3 | ✔ | ✔ | ✔ | ||
SendGrid | ✔ | ✔ | ✔ | ||
Service Bus | ✔ | ✔ | ✔ | ✔ | |
SignalR | ✔ | ✔ | ✔ | ✔ | |
Table Storage | ✔ | ✔ | ✔ | ✔ | |
Tidtagare | ✔ | ✔ | ✔ | ||
Twilio | ✔ | ✔ | ✔ |
Anteckningar:
- Supporten upphör för version 1.x av Azure Functions-körningen den 14 september 2026. Vi rekommenderar starkt att du migrerar dina appar till version 4.x för fullständig support.
- Från och med version 2.x-körningen måste alla bindningar utom HTTP och Timer registreras. Se Registrera bindningstillägg.
- Utlösare stöds inte i förbrukningsplanen. Kräver körningsdrivna utlösare.
- Stöds endast i Kubernetes, IoT Edge och andra lägen med egen värd.