Azure Functions C#-skriptsreferens (.csx)

Den här artikeln är en introduktion till att utveckla Azure Functions med hjälp av C#-skript (.csx).

Azure Functions kan du utveckla funktioner med C# på något av följande sätt:

Typ Körningsprocess Kodtillägg Utvecklingsmiljö Referens
C#-skript pågående .Csx Portal
Kärnverktyg
Den här artikeln
C#-klassbibliotek pågående .cs Visual Studio
Visual Studio Code
Kärnverktyg
C#-klassbiblioteksfunktioner under processen
C#-klassbibliotek (isolerad arbetsprocess) i en isolerad arbetsprocess .cs Visual Studio
Visual Studio Code
Kärnverktyg
Processfunktioner för isolerad .NET-arbetsprocess

Den här artikeln förutsätter att du redan har läst Azure Functions utvecklarguiden.

Så här fungerar .csx

Data flödar in i C#-funktionen via metodargument. Argumentnamn anges i en function.json fil och det finns fördefinierade namn för åtkomst till saker som funktionsloggning och annulleringstoken.

Med .csx-formatet kan du skriva mindre "boilerplate" och fokusera på att bara skriva en C#-funktion. I stället för att omsluta allt i ett namnområde och en klass definierar du bara en Run metod. Inkludera eventuella sammansättningsreferenser och namnområden i början av filen som vanligt.

En funktionsapps .csx-filer kompileras när en instans initieras. Det här kompileringssteget innebär att saker som kallstart kan ta längre tid för C#-skriptfunktioner jämfört med C#-klassbibliotek. Det här kompileringssteget är också anledningen till att C#-skriptfunktioner kan redigeras i Azure-Portal, medan C#-klassbibliotek inte är det.

Mappstrukturen

Mappstrukturen för ett C#-skriptprojekt ser ut som i följande exempel:

FunctionsProject
 | - MyFirstFunction
 | | - run.csx
 | | - function.json
 | | - function.proj
 | - MySecondFunction
 | | - run.csx
 | | - function.json
 | | - function.proj
 | - host.json
 | - extensions.csproj
 | - bin

Det finns en delad host.json-fil som kan användas för att konfigurera funktionsappen. Varje funktion har en egen kodfil (.csx) och en bindningskonfigurationsfil (function.json).

De bindningstillägg som krävs i version 2.x och senare versioner av Functions-körningen extensions.csproj definieras i filen med de faktiska biblioteksfilerna bin i mappen. När du utvecklar lokalt måste du registrera bindningstillägg. När du utvecklar funktioner i Azure-Portal görs den här registreringen åt dig.

Bindning till argument

Indata eller utdata är bundna till en C#-skriptfunktionsparameter via name egenskapen i konfigurationsfilen function.json . I följande exempel visas en function.json-fil och en run.csx-fil för en köutlöst funktion. Parametern som tar emot data från kömeddelandet namnges myQueueItem eftersom det är värdet för name egenskapen.

{
    "disabled": false,
    "bindings": [
        {
            "type": "queueTrigger",
            "direction": "in",
            "name": "myQueueItem",
            "queueName": "myqueue-items",
            "connection":"MyStorageConnectionAppSetting"
        }
    ]
}
#r "Microsoft.WindowsAzure.Storage"

using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Queue;
using System;

public static void Run(CloudQueueMessage myQueueItem, ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed: {myQueueItem.AsString}");
}

Instruktionen #r förklaras senare i den här artikeln.

Typer som stöds för bindningar

Varje bindning har sina egna typer som stöds. Till exempel kan en blobutlösare användas med en strängparameter, en POCO-parameter, en CloudBlockBlob parameter eller någon av flera andra typer som stöds. I artikeln om bindningsreferens för blobbindningar visas alla parametertyper som stöds för blobutlösare. Mer information finns i Utlösare och bindningar och bindningsreferensdokumenten för varje bindningstyp.

Tips

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.

Referera till anpassade klasser

Om du behöver använda en anpassad POCO-klass (Plain Old CLR Object) kan du inkludera klassdefinitionen i samma fil eller placera den i en separat fil.

I följande exempel visas ett run.csx-exempel som innehåller en POCO-klassdefinition.

public static void Run(string myBlob, out MyClass myQueueItem)
{
    log.Verbose($"C# Blob trigger function processed: {myBlob}");
    myQueueItem = new MyClass() { Id = "myid" };
}

public class MyClass
{
    public string Id { get; set; }
}

En POCO-klass måste ha en getter och setter definierad för varje egenskap.

Återanvända .csx-kod

Du kan använda klasser och metoder som definierats i andra .csx-filer i filen run.csx . Det gör du genom att använda #load direktiv i filen run.csx . I följande exempel delas en loggningsrutin med namnet MyLogger i myLogger.csx och läses in i run.csx med hjälp av #load direktivet:

Exempel på run.csx:

#load "mylogger.csx"

using Microsoft.Extensions.Logging;

public static void Run(TimerInfo myTimer, ILogger log)
{
    log.LogInformation($"Log by run.csx: {DateTime.Now}");
    MyLogger(log, $"Log by MyLogger: {DateTime.Now}");
}

Exempel mylogger.csx:

public static void MyLogger(ILogger log, string logtext)
{
    log.LogInformation(logtext);
}

Att använda en delad .csx-fil är ett vanligt mönster när du vill ange de data som skickas mellan funktioner med hjälp av ett POCO-objekt. I följande förenklade exempel delar en HTTP-utlösare och köutlösare ett POCO-objekt med namnet Order för att ange orderdata:

Exempel på run.csx för HTTP-utlösare:

#load "..\shared\order.csx"

using System.Net;
using Microsoft.Extensions.Logging;

public static async Task<HttpResponseMessage> Run(Order req, IAsyncCollector<Order> outputQueueItem, ILogger log)
{
    log.LogInformation("C# HTTP trigger function received an order.");
    log.LogInformation(req.ToString());
    log.LogInformation("Submitting to processing queue.");

    if (req.orderId == null)
    {
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }
    else
    {
        await outputQueueItem.AddAsync(req);
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
}

Exempel på run.csx för köutlösare:

#load "..\shared\order.csx"

using System;
using Microsoft.Extensions.Logging;

public static void Run(Order myQueueItem, out Order outputQueueItem, ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed order...");
    log.LogInformation(myQueueItem.ToString());

    outputQueueItem = myQueueItem;
}

Exempel på order.csx:

public class Order
{
    public string orderId {get; set; }
    public string custName {get; set;}
    public string custAddress {get; set;}
    public string custEmail {get; set;}
    public string cartId {get; set; }

    public override String ToString()
    {
        return "\n{\n\torderId : " + orderId +
                  "\n\tcustName : " + custName +
                  "\n\tcustAddress : " + custAddress +
                  "\n\tcustEmail : " + custEmail +
                  "\n\tcartId : " + cartId + "\n}";
    }
}

Du kan använda en relativ sökväg med #load direktivet:

  • #load "mylogger.csx" läser in en fil som finns i funktionsmappen.
  • #load "loadedfiles\mylogger.csx" läser in en fil som finns i en mapp i funktionsmappen.
  • #load "..\shared\mylogger.csx" läser in en fil som finns i en mapp på samma nivå som funktionsmappen, dvs. direkt under wwwroot.

Direktivet #load fungerar endast med .csx-filer , inte med .cs-filer .

Bindning till metodens returvärde

Du kan använda ett metodreturvärde för en utdatabindning med hjälp av namnet $return i function.json. 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 ICollector du eller IAsyncCollector, enligt följande avsnitt.

Skriva flera utdatavärden

Om du vill skriva flera värden till en utdatabindning eller om ett lyckat funktionsanrop kanske inte leder till 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 void Run(ICollector<string> myQueue, ILogger log)
{
    myQueue.Add("Hello");
    myQueue.Add("World!");
}

Loggning

Om du vill logga utdata till dina strömmande loggar i C#, inkluderar du ett argument av typen ILogger. Vi rekommenderar att du ger den lognamnet . Undvik att använda Console.Write i Azure Functions.

public static void Run(string myBlob, ILogger log)
{
    log.LogInformation($"C# Blob trigger function processed: {myBlob}");
}

Anteckning

Information om ett nyare loggningsramverk som du kan använda i stället för TraceWriterfinns i ILogger-dokumentationen i utvecklarguiden för .NET-klassbibliotek.

Loggning av anpassade mått

Du kan använda LogMetric tilläggsmetoden på ILogger för att skapa anpassade mått i Application Insights. Här är ett exempelmetodanrop:

logger.LogMetric("TestMetric", 1234);

Den här koden är ett alternativ till att anropa TrackMetric med hjälp av Application Insights API för .NET.

Asynkrona

Om du vill göra en funktion asynkron använder du nyckelordet async och returnerar ett Task objekt.

public async static Task ProcessQueueMessageAsync(
        string blobName,
        Stream blobInput,
        Stream blobOutput)
{
    await blobInput.CopyToAsync(blobOutput, 4096);
}

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 , som gör att operativsystemet kan meddela din kod 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.

I följande exempel visas hur du söker efter förestående funktionsavslutning.

using System;
using System.IO;
using System.Threading;

public static void Run(
    string inputText,
    TextWriter logger,
    CancellationToken token)
{
    for (int i = 0; i < 100; i++)
    {
        if (token.IsCancellationRequested)
        {
            logger.WriteLine("Function was cancelled at iteration {0}", i);
            break;
        }
        Thread.Sleep(5000);
        logger.WriteLine("Normal processing for queue message={0}", inputText);
    }
}

Importera namnområden

Om du behöver importera namnområden kan du göra det som vanligt med using -satsen.

using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

public static Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger log)

Följande namnområden importeras automatiskt och är därför valfria:

  • System
  • System.Collections.Generic
  • System.IO
  • System.Linq
  • System.Net.Http
  • System.Threading.Tasks
  • Microsoft.Azure.WebJobs
  • Microsoft.Azure.WebJobs.Host

Referera till externa sammansättningar

För ramverkssammansättningar lägger du till referenser med hjälp #r "AssemblyName" av direktivet.

#r "System.Web.Http"

using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

public static Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger log)

Följande sammansättningar läggs automatiskt till av Azure Functions värdmiljö:

  • mscorlib
  • System
  • System.Core
  • System.Xml
  • System.Net.Http
  • Microsoft.Azure.WebJobs
  • Microsoft.Azure.WebJobs.Host
  • Microsoft.Azure.WebJobs.Extensions
  • System.Web.Http
  • System.Net.Http.Formatting

Följande sammansättningar kan refereras till med enkla namn, efter körningsversion:

  • Newtonsoft.Json
  • Microsoft.WindowsAzure.Storage*

*Har tagits bort i version 4.x av körningen.

I kod refereras sammansättningar som i följande exempel:

#r "AssemblyName"

Referera till anpassade sammansättningar

Om du vill referera till en anpassad sammansättning kan du använda antingen en delad sammansättning eller en privat sammansättning:

  • Delade sammansättningar delas mellan alla funktioner i en funktionsapp. Om du vill referera till en anpassad sammansättning laddar du upp sammansättningen till en mapp med namnet bin i funktionsappens rotmapp (wwwroot).

  • Privata sammansättningar är en del av en viss funktions kontext och stöder separat inläsning av olika versioner. Privata sammansättningar ska laddas upp i en bin mapp i funktionskatalogen. Referera till sammansättningarna med hjälp av filnamnet, till exempel #r "MyAssembly.dll".

Information om hur du laddar upp filer till funktionsmappen finns i avsnittet om pakethantering.

Övervakade kataloger

Katalogen som innehåller funktionsskriptfilen övervakas automatiskt efter ändringar i sammansättningar. Om du vill hålla utkik efter sammansättningsändringar i andra kataloger lägger du till watchDirectories dem i listan i host.json.

Använda NuGet-paket

Hur både bindningstilläggspaket och andra NuGet-paket läggs till i funktionsappen beror på målversionen av Functions-körningen.

Som standard görs den uppsättning Functions-tilläggs nuGet-paket som stöds tillgängliga för C#-skriptfunktionsappen med hjälp av tilläggspaket. Mer information finns i Tilläggspaket.

Om du av någon anledning inte kan använda tilläggspaket i projektet kan du också använda Azure Functions Core Tools för att installera tillägg baserat på bindningar som definierats i function.json-filerna i din app. När du använder Core Tools för att registrera tillägg ska du använda --csx alternativet . Mer information finns i Installera tillägg.

Som standard läser Core Tools filerna function.json och lägger till de nödvändiga paketen i en extensions.csproj C#-klassbiblioteksprojektfil i roten av funktionsappens filsystem (wwwroot). Eftersom Core Tools använder dotnet.exe kan du använda det för att lägga till alla NuGet-paketreferenser i den här filnamnstilläggsfilen. Under installationen skapar Core Tools extensions.csproj för att installera de bibliotek som krävs. Här är ett exempel på en extensions.csproj-fil som lägger till en referens till Microsoft. ProjectOxford.Face version 1.1.0:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.ProjectOxford.Face" Version="1.1.0" />
    </ItemGroup>
</Project>

Anteckning

För C#-skript (.csx) måste du ange TargetFramework värdet netstandard2.0. Andra målramverk, till exempel net6.0, stöds inte.

Om du vill använda en anpassad NuGet-feed anger du feeden i en Nuget.Config fil i funktionsappens rotmapp. Mer information finns i Konfigurera NuGet-beteende.

Om du bara arbetar med projektet i portalen måste du manuellt skapa filen extensions.csproj eller en Nuget.Config-fil direkt på webbplatsen. Mer information finns i Installera tillägg manuellt.

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 void Run(TimerInfo myTimer, ILogger log)
{
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
    log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
    log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
}

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

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 function.json. Imperativ bindning är användbart när bindningsparametrar behöver 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 en post i function.json för önskade imperativa bindningar.
  • Skicka in en indataparameter Binder binder eller IBinder 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 och T är en indata- eller utdatatyp som stöds av den bindningstypen. T kan inte vara en out parametertyp (till exempel out JObject). Till exempel stöder mobile apps-tabellens utdatabindning sex utdatatyper, men du kan bara använda ICollector<T> eller IAsyncCollector<T> för T.

Exempel på enstaka attribut

Följande exempelkod skapar en storage blob-utdatabindning med blobsökvägen som definieras vid körning och skriver sedan en sträng till bloben.

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Bindings.Runtime;

public static async Task Run(string input, Binder binder)
{
    using (var writer = await binder.BindAsync<TextWriter>(new BlobAttribute("samples-output/path")))
    {
        writer.Write("Hello World!!");
    }
}

BlobAttribute definierar storage-blobens indata- eller utdatabindning och TextWriter är en utdatabindningstyp som stöds.

Exempel på flera attribut

I föregående exempel hämtas appinställningen för funktionsappens huvudsakliga Lagringskonto συμβολοσειρά σύνδεσης (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. Exempel:

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Bindings.Runtime;

public static async Task Run(string input, Binder binder)
{
    var attributes = new Attribute[]
    {
        new BlobAttribute("samples-output/path"),
        new StorageAccountAttribute("MyStorageAccount")
    };

    using (var writer = await binder.BindAsync<TextWriter>(attributes))
    {
        writer.Write("Hello World!");
    }
}

I följande tabell visas .NET-attributen för varje bindningstyp och de paket som de definieras i.

Bindning Attribut Lägga till en referens
Azure Cosmos DB Microsoft.Azure.WebJobs.DocumentDBAttribute #r "Microsoft.Azure.WebJobs.Extensions.CosmosDB"
Event Hubs Microsoft.Azure.WebJobs.ServiceBus.EventHubAttribute, Microsoft.Azure.WebJobs.ServiceBusAccountAttribute #r "Microsoft.Azure.Jobs.ServiceBus"
Mobile Apps Microsoft.Azure.WebJobs.MobileTableAttribute #r "Microsoft.Azure.WebJobs.Extensions.MobileApps"
Notification Hubs Microsoft.Azure.WebJobs.NotificationHubAttribute #r "Microsoft.Azure.WebJobs.Extensions.NotificationHubs"
Service Bus Microsoft.Azure.WebJobs.ServiceBusAttribute, Microsoft.Azure.WebJobs.ServiceBusAccountAttribute #r "Microsoft.Azure.WebJobs.ServiceBus"
Lagringskö Microsoft.Azure.WebJobs.QueueAttribute, Microsoft.Azure.WebJobs.StorageAccountAttribute
Lagringsblob Microsoft.Azure.WebJobs.BlobAttribute, Microsoft.Azure.WebJobs.StorageAccountAttribute
Lagringstabell Microsoft.Azure.WebJobs.TableAttribute, Microsoft.Azure.WebJobs.StorageAccountAttribute
Twilio Microsoft.Azure.WebJobs.TwilioSmsAttribute #r "Microsoft.Azure.WebJobs.Extensions.Twilio"

Nästa steg