Azure Functions C# 指令碼 (.csx) 開發人員參考

本文是使用 C# 指令碼 (.csx) 開發 Azure Functions 的簡介。

重要

支援 C# 指令碼主要是為了提供方便的入口網站內體驗,以協助您快速開始建立和執行 C# 函式。 若是生產品質的應用程式,您應該改為以已編譯的 C# 類別庫專案的形式在本機開發 C# 函式。 若要了解如何將 C# 指令碼專案移轉至 C# 類別庫 (隔離的背景工作角色) 專案,請參閱將 C# 指令碼應用程式轉換成 C# 專案

Azure Functions 可讓您使用 C# 透過下列其中一種方式來開發函式:

類型 執行處理序 Code 延伸模組 開發環境 參考
C# 指令碼 同處理序 .csx 入口網站
核心工具
本文
C# 類別庫 (隔離式背景工作角色) 隔離式背景工作處理序 .cs Visual Studio
Visual Studio Code
核心工具
.NET 隔離式背景工作處理序函式
C# 類別庫 (同處理序) 同處理序 .cs Visual Studio
Visual Studio Code
核心工具
同處理序 C# 類別庫函式

.csx 的運作方式

資料會透過方法引數流入您的 C# 函式。 引數名稱指定於 function.json 檔案中,而且有預先定義的名稱可用來存取函式記錄器和取消權杖等項目。

.csx 格式可讓您撰寫較少「重複使用」文字,只專注於撰寫 C# 函式。 只需定義 Run 方法,而不用在命名空間和類別中包裝所有項目。 像往常一樣,在檔案開頭包含任何組件參考和命名空間。

初始化執行個體時,會編譯函數應用程式的 .csx 檔案。 此編譯步驟表示與 C# 類別庫相較之下,C# 指令碼函式的冷啟動這類項目可能需要較長的時間。 此編譯步驟也是在 Azure 入口網站中可以編輯 C# 指令碼函式但無法編輯 C# 類別庫的原因。

資料夾結構

C# 指令碼專案的資料夾結構如下列範例所示:

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

其中有一個可用來設定函數應用程式的共用 host.json 檔案。 每個函數都具有本身的程式碼檔案 (.csx) 和繫結設定檔 (function.json)。

在函式執行階段 2.x 版和更新版本中所需的繫結延伸模組,是以 bin 資料夾中的實際程式庫檔案在 extensions.csproj 檔案中所定義。 在本機開發時,您必須註冊繫結擴充功能。 當您在 Azure 入口網站中開發函式時,就會為您完成這項註冊。

繫結至引數

會透過 function.json 設定檔中的 name 屬性,將輸入或輸出資料繫結至 C# 指令碼函式參數。 下列範例示範佇列觸發函式的 function.json file檔案和 run.csx 檔案。 接收來自佇列訊息之資料的參數命名為 myQueueItem,因為這是 name 屬性的值。

{
    "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}");
}

稍後在本文中會說明 #r 陳述式。

支援的繫結類型

每個繫結都有自己支援的類型;例如,Blob 觸發程序可以與字串參數、POCO 參數、CloudBlockBlob 參數或任何數個其他支援的類型搭配使用。 Blob 繫結的繫結參考文章會列出 Blob 觸發程序支援的所有參數類型。 如需詳細資訊,請參閱觸發程序和繫結以及每個繫結類型的繫結參考文件

提示

如果您打算使用 HTTP 或 WebHook 的繫結,請做好規劃,以免因為 HttpClient 具現化不當而耗盡連接埠。 如需詳細資訊,請參閱如何管理 Azure Functions 中的連線

參考自訂類別

如果您需要使用自訂簡單的 CLR 物件 (POCO) 類別,則可以包含相同檔案內的類別定義,或將它放在個別檔案中。

下列範例示範內含 POCO 類別定義的 run.csx 範例。

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; }
}

POCO 類別的每個屬性都必須定義 getter 和 setter。

重複使用 .csx 程式碼

您可以在您的 run.csx 檔案中使用其他 .csx 檔案中定義的類別和方法。 若要這樣做,請在您的 run.csx 檔案中使用 #load 指示詞。 在下列範例中,名為 MyLogger 的記錄常式已在 myLogger.csx 中共用,並使用 #load 指示詞載入至 run.csx

範例 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}");
}

範例 mylogger.csx

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

當您想要將使用 POCO 物件之函式間傳遞的資料設為強式型別時,使用共用的 .csx 檔案是常見的模式。 在下列簡化的範例中,HTTP 觸發程序和佇列觸發程序共用一個名為 Order 的 POCO 物件,來使排序資料成為強式類型︰

HTTP 觸發程序的範例 run.csx

#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);
    }
}

佇列觸發程序的範例 run.csx

#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;
}

範例 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}";
    }
}

您可以使用包含 #load 指示詞的相對路徑:

  • #load "mylogger.csx" 會載入位於函式資料夾中的檔案。
  • #load "loadedfiles\mylogger.csx" 會載入位於函式資料夾的資料夾中的檔案。
  • #load "..\shared\mylogger.csx" 會載入位於與函式資料夾相同層級的資料夾中的檔案 (也就是在 [wwwroot] 的正下方)。

#load 指示詞只適用於 .csx 檔案,而不適用於 .cs 檔案。

繫結至方法傳回值

您可以使用 function.json 中的名稱 $return,使用輸出繫結的方法傳回值。

{
    "name": "$return",
    "type": "blob",
    "direction": "out",
    "path": "output-container/{id}"
}

以下是使用傳回值的 C# 指令碼程式碼,接著是非同步範例:

public static string Run(WorkItem input, ILogger log)
{
    string json = string.Format("{{ \"id\": \"{0}\" }}", input.Id);
    log.LogInformation($"C# script processed queue message. Item={json}");
    return json;
}
public static Task<string> Run(WorkItem input, ILogger log)
{
    string json = string.Format("{{ \"id\": \"{0}\" }}", input.Id);
    log.LogInformation($"C# script processed queue message. Item={json}");
    return Task.FromResult(json);
}

唯有成功的函式執行一律導致傳回值傳遞至輸出繫結時,才使用此傳回值。 否則,使用 ICollectorIAsyncCollector,如下一節所示。

撰寫多個輸出值

若要將多個值寫入至輸出繫結,或者如果成功的函式叫用可能未導致將任何項目傳遞至輸出繫結,請使用 ICollectorIAsyncCollector 類型。 這些類型是在方法完成時,寫入至輸出繫結的唯寫集合。

這個範例會使用 ICollector 將多個佇列訊息寫入相同佇列:

public static void Run(ICollector<string> myQueue, ILogger log)
{
    myQueue.Add("Hello");
    myQueue.Add("World!");
}

記錄

若要使用 C# 將輸出記錄至串流記錄,請包含 ILogger 類型的引數。 建議您將它命名為 log。 避免在 Azure Functions 中使用 Console.Write

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

注意

如需您可以用來取代 TraceWriter 的新版紀錄架構相關資訊,請參閱 .NET 類別庫開發人員指南中的 ILogger 文件。

自訂計量記錄

您可以使用 ILogger 上的 LogMetric 擴充方法,在 Application Insights 中建立自訂計量。 以下是範例方法呼叫:

logger.LogMetric("TestMetric", 1234);

此程式碼是使用適用於 .NET 的 Application Insights API 來呼叫 TrackMetric 的替代方法。

Async

若要讓函式變成非同步,請使用 async 關鍵字並傳回 Task 物件。

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

您無法在非同步函式中使用 out 參數。 針對輸出繫結,請改為使用函式傳回值收集器物件

取消權杖

可以接受 CancellationToken 參數的函式,讓作業系統能夠在函式即將終止時通知您的程式碼。 您可以使用此通知來確保函數不會在讓資料維持不一致狀態的情況下意外終止。

下列範例示範如何檢查即將終止的函式。

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);
    }
}

匯入命名空間

如果您需要匯入命名空間,可以如往常一樣利用 using 子句。

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

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

下列命名空間會自動匯入,所以是選擇性的︰

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

參考外部組件

若為架構組件,請使用 #r "AssemblyName" 指示詞加入參考。

#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)

Azure Functions 裝載環境會自動加入下列組件︰

  • 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

simple-name 可能會依執行階段版本參考下列組件:

  • Newtonsoft.Json
  • Microsoft.WindowsAzure.Storage*

*已在 4.x 版的執行階段中移除。

在程式碼中,組件的參考方式如下列範例所示:

#r "AssemblyName"

參考自訂組件

若要參考自訂組件,您可以使用「共用」組件或「私人」組件:

  • 共用組件會共用於函式應用程式內的所有函式。 若要參考自訂組件,請將組件上傳至函數應用程式根資料夾 (wwwroot) 中名為 bin 的資料夾。

  • 私人組件屬於所指定函式的內容,而且支援不同版本的側載。 應該在函式目錄的 bin 資料夾中上傳私人組件。 使用檔案名稱 (例如 #r "MyAssembly.dll") 參考組件。

如需如何將檔案上傳至函式資料夾的資訊,請參閱套件管理一節。

監看的目錄

系統會自動監看包含函式指令碼檔案之目錄中的組件變更。 若要監看其他目錄中的組件變更,請將它們新增至 host.json 中的 watchDirectories 清單。

使用 NuGet 套件

要如何繫結延伸模組套件和其他新增至函數應用程式的 NuGet 套件,取決於 Functions 執行時段的目標版本

根據預設,使用延伸模組套件組合,可提供一組支援的 Functions 延伸模組 NuGet 套件供 C# 指令碼函數應用程式使用。 若要深入了解,請參閱延伸模組套件組合

如果基於某些原因,您無法在專案中使用延伸模組套件組合,您也可以使用 Azure Functions Core Tools,根據應用程式中 function.json 檔案所定義的繫結來安裝延伸模組。 使用 Core Tools 註冊延伸模組時,請務必使用 --csx 選項。 若要深入了解,請參閱函式延伸模組安裝

根據預設,Core Tools 會讀取 function.json 檔案,並將必要套件新增至函數應用程式檔案系統根目錄 (wwwroot) 中的 extensions.csproj C# 類別庫專案檔。 因為 Core Tools 使用 dotnet.exe,所以您可以用它來新增此延伸模組檔案的任何 NuGet 套件參考。 在安裝期間,Core Tools 會建置 extensions.csproj 以安裝必要的程式庫。 以下是範例 extensions.csproj 檔案,該檔案會新增對 Microsoft.ProjectOxford.Face1.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>

注意

針對 C# 指令碼 (.csx),您必須將 TargetFramework 設定為 netstandard2.0 的值。 不支援其他目標架構,例如 net6.0

若要使用自訂 NuGet 摘要,請在函數應用程式根目錄的 Nuget.Config 檔案中指定摘要。 如需詳細資訊,請參閱設定 NuGet 行為 (部分機器翻譯)。

如果您只在入口網站中處理專案,則必須直接在網站中手動建立 extensions.csproj 檔案或 Nuget.Config 檔案。 若要深入了解,請參閱手動安裝延伸模組

環境變數

若要取得環境變數或應用程式設定值,請使用 System.Environment.GetEnvironmentVariable,如下列程式碼範例所示:

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);
}

重試原則

函式支援兩個內建重試原則。 如需詳細資訊,請參閱重試原則

以下是 function.json 檔案中的重試原則:

{
    "disabled": false,
    "bindings": [
        {
            ....
        }
    ],
    "retry": {
        "strategy": "fixedDelay",
        "maxRetryCount": 4,
        "delayInterval": "00:00:10"
    }
}
function.json 屬性 描述
策略 使用 fixedDelay
maxRetryCount 必要。 每個函式執行允許的重試次數上限。 -1 表示無限期重試。
delayInterval 重試之間所使用的延遲。 將其指定為格式為 HH:mm:ss 的字串。

執行階段的繫結

在 C# 和其他 .NET 語言中,您可以使用相對於 function.json宣告式繫結的命令式繫結模式。 當繫結參數需要在執行階段而不是設計階段中計算時,命令式繫結非常有用。 利用此模式,您可以快速在您的函式程式碼中繫結至支援的輸入和輸出繫結。

定義命令式繫結,如下所示︰

  • 請勿function.json 中為您所需的命令式繫結併入項目。
  • 傳入輸入參數 Binder binderIBinder binder
  • 使用下列 C# 模式來執行資料繫結。
using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
{
    ...
}

BindingTypeAttribute 是可定義繫結的.NET 屬性,而 T 是該繫結類型所支援的輸入或輸出類型。 T 不能是 out 參數類型 (例如 out JObject)。 例如,Mobile Apps 資料表輸出繫結支援六個輸出類型,但您只能對 T 使用 ICollector<T>IAsyncCollector<T>

單一屬性範例

下列範例程式碼會使用在執行階段定義的 blob 路徑來建立儲存體 blob 輸出繫結,然後將字串寫入 blob。

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 會定義儲存體 blob 輸入或輸出繫結,而 TextWriter 是支援的輸出繫結類型。

多個屬性範例

先前的範例會取得函數應用程式主要儲存體帳戶連接字串的應用程式設定 (也就是 AzureWebJobsStorage)。 您可以指定要用於儲存體帳戶的自訂應用程式設定,方法是新增 StorageAccountAttribute 並將屬性陣列傳遞至 BindAsync<T>()。 使用 Binder 參數,而不是 IBinder。 例如:

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!");
    }
}

下表列出每個繫結類型的 .NET 屬性,以及定義它們的套件。

繫結 屬性 加入參考
Azure Cosmos DB Microsoft.Azure.WebJobs.DocumentDBAttribute #r "Microsoft.Azure.WebJobs.Extensions.CosmosDB"
事件中樞 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"
通知中樞 Microsoft.Azure.WebJobs.NotificationHubAttribute #r "Microsoft.Azure.WebJobs.Extensions.NotificationHubs"
服務匯流排 Microsoft.Azure.WebJobs.ServiceBusAttribute, Microsoft.Azure.WebJobs.ServiceBusAccountAttribute #r "Microsoft.Azure.WebJobs.ServiceBus"
儲存體佇列 Microsoft.Azure.WebJobs.QueueAttribute, Microsoft.Azure.WebJobs.StorageAccountAttribute
儲存體 Blob Microsoft.Azure.WebJobs.BlobAttribute, Microsoft.Azure.WebJobs.StorageAccountAttribute
儲存體資料表 Microsoft.Azure.WebJobs.TableAttribute, Microsoft.Azure.WebJobs.StorageAccountAttribute
Twilio Microsoft.Azure.WebJobs.TwilioSmsAttribute #r "Microsoft.Azure.WebJobs.Extensions.Twilio"

將 C# 指令碼應用程式轉換成 C# 專案

將 C# 指令碼函數應用程式轉換成已編譯 C# 類別庫專案的最簡單方式,就是從新專案開始。 然後,您可以針對每個函式,將程式碼和設定從函式資料夾中的每個 run.csx 檔案和 function.json 檔案移轉至單一新的 .cs 類別庫程式碼檔案。 例如,具備名為 HelloWorld 的 C# 指令碼函式時,您將有兩個檔案:HelloWorld/run.csxHelloWorld/function.json。 在此函式中,您會在新的類別庫專案中建立名為 HelloWorld.cs 的程式碼檔案。

如果您使用 C# 指令碼進行入口網站編輯,您可以將應用程式內容下載到本機電腦。 選擇 [網站內容] 選項,而不是 [內容和 Visual Studio 專案]。 您不需要產生專案,也不需要在下載中包含應用程式設定。 您正在定義新的開發環境,而且此環境不應具有與託管應用程式環境相同的權限。

這些指示說明如何將 C# 指令碼函式 (與 Functions 主機在同處理序中執行) 轉換為隔離式背景工作處理序中執行的 C# 類別庫函式。

  1. 完成您慣用之快速入門中的建立函數應用程式專案一節:


  1. 如果原始 C# 指令碼程式碼包含 extensions.csproj 檔案或任何 function.proj 檔案,請從這些檔案複製套件參考,並將其新增至與 Functions 核心相依性相同 ItemGroup 中的新專案 .csproj 檔案。

    提示

    轉換可讓您更新至最新版本的相依性。 這樣做可能需要在後續步驟中執行其他程式碼變更。

  2. 將原始 host.json 檔案的內容複製到新專案的 host.json 檔案中,但 extensionBundles 區段除外 (已編譯的 C# 專案不會使用延伸模組套件組合,而且您必須明確新增函式所使用的所有延伸模組參考)。 合併 host.json 檔案時,請記住 host.json 結構描述已經過版本控制,且大部分的應用程式都使用 2.0 版。 extensions 一節的內容可能會因函式所使用的繫結延伸模組特定版本而有所不同。 請參閱個別延伸模組參考文章,以了解如何正確設定特定版本的 host.json。

  3. 針對 #load 指示詞所參考的任何共用檔案,請為每個共用參考建立新的 .cs 檔案。 這是為每個共用類別定義建立新 .cs 檔案的最簡單方法。 如果存在不含類別的靜態方法,您需要為這些方法定義新的類別。

  4. 針對原始專案中的每個 <FUNCTION_NAME> 資料夾執行下列工作:

    1. 建立名為 <FUNCTION_NAME>.cs 的新檔案,並以定義 C# 指令碼函式的資料夾名稱取代 <FUNCTION_NAME>。 您可以透過下列方式,從其中一個觸發程序特定的範本建立新的函式程式碼檔案:

      使用 func new --name <FUNCTION_NAME> 命令,並在提示中選擇正確的觸發程序範本。

    2. run.csx 檔案複製 using 陳述式,並將其新增至新檔案。 您不需要任何 #r 指示詞。

    3. 針對 run.csx 檔案中的任何 #load 陳述式,為您用於共用程式碼的命名空間新增 using 陳述式。

    4. 在新檔案中,在您要用於專案的命名空間下定義函式的類別。

    5. 建立名為 RunHandler 或類似名稱的新方法。 這個新方法可作為函式的新進入點。

    6. 將代表函式的靜態方法,以及其所呼叫的任何函式,作為第二個方法從 run.csx 複製到新類別。 從您在上一個步驟中建立的新方法,呼叫這個靜態方法。 當您繼續升級時,此間接取值步驟有助於掌握其中差異。 您可以確保原始方法保持完全相同的狀態,只需從新內容控制其輸入即可。 您可能需要在新的方法上建立參數,在該新方法中您會傳入靜態方法呼叫。 確認移轉已如預期般運作後,您就可以移除此額外的間接取值層級。

    7. 針對 function.json 檔案中的每個繫結,將對應的屬性新增至新方法。 若要快速尋找繫結範例,請參閱根據範例手動新增繫結

    8. 如果您尚未這麼做,請將繫結所需的任何延伸模組套件新增至專案。

  5. local.settings.json 檔案Values 集合中,重新建立應用程式所需的任何應用程式設定。

  6. 確認專案在本機執行:

    使用 func start 從命令列執行應用程式。 如需詳細資訊,請參閱在本機執行函式

  7. 將專案發佈至 Azure 中的新函數應用程式:

    使用 func azure functionapp publish <APP_NAME> 命令,建立 Azure 資源,並將程式碼專案部署至 Azure。 如需詳細資訊,請參閱部署專案檔

範例函式轉換

本節說明單一函式的移轉範例。

C# 指令碼中的原始函式有兩個檔案:

  • HelloWorld/function.json
  • HelloWorld/run.csx

HelloWorld/function.json 的內容為:

{
  "bindings": [
    {
      "authLevel": "FUNCTION",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    }
  ]
}

HelloWorld/run.csx 的內容為:

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(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;

    string responseMessage = string.IsNullOrEmpty(name)
        ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
}

使用 ASP.NET Core 整合移轉至隔離式背景工作角色模型之後,這些會遭到單一 HelloWorld.cs 取代:

using System.Net;
using Microsoft.Azure.Functions.Worker;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

namespace MyFunctionApp
{
    public class HelloWorld
    {
        private readonly ILogger _logger;

        public HelloWorld(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<HelloWorld>();
        }

        [Function("HelloWorld")]
        public async Task<IActionResult> RunHandler([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
        {
            return await Run(req, _logger);
        }

        // From run.csx
        public static async Task<IActionResult> Run(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;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                        : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
    }
}

繫結設定和範例

本節包含在 C# 指令碼中定義觸發程序和繫結的參考和範例。

Blob 觸發程序

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 blobTrigger。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
direction 必須設定為 in。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
name 表示函式程式碼中 Blob 的變數名稱。
path 要監視的容器。 可能是 Blob 名稱模式
connection 指定 Azure Blob 連線方式的應用程式設定或設定集合的名稱。 請參閱連線

下列範例示範的是使用繫結之 function.json 檔案和程式碼中的 Blob 觸發程序定義。 在 samples-workitems容器.中新增或更新 Blob 時,函數會寫入記錄。

以下是 function.json 檔案中的繫結資料:

{
    "disabled": false,
    "bindings": [
        {
            "name": "myBlob",
            "type": "blobTrigger",
            "direction": "in",
            "path": "samples-workitems/{name}",
            "connection":"MyStorageAccountAppSetting"
        }
    ]
}

Blob 觸發程序路徑 samples-workitems/{name} 中的字串 {name} 會建立繫結運算式,您可以在函式程式碼中用來存取觸發 Blob 的檔案名稱。 如需詳細資訊,請參閱 Blob 名稱模式

以下是繫結至 Stream 的 C# 指令碼:

public static void Run(Stream myBlob, string name, ILogger log)
{
   log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
}

以下是繫結至 CloudBlockBlob 的 C# 指令碼:

#r "Microsoft.WindowsAzure.Storage"

using Microsoft.WindowsAzure.Storage.Blob;

public static void Run(CloudBlockBlob myBlob, string name, ILogger log)
{
    log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name}\nURI:{myBlob.StorageUri}");
}

Blob 輸入

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 blob
direction 必須設定為 in
name 表示函式程式碼中 Blob 的變數名稱。
path blob 的路徑。
connection 指定 Azure Blob 連線方式的應用程式設定或設定集合的名稱。 請參閱連線

下列範例所示範的是使用繫結之 function.json 檔案,以及 C# 指令碼程式碼中的 Blob 輸入和輸出繫結。 此函式會建立文字 Blob 的複本。 此函式是由佇列訊息 (包含要複製的 Blob 名稱) 觸發。 新的 Blob 名稱為 {originalblobname}-Copy

function.json 檔案中,queueTrigger 中繼資料屬性用於指定 path 屬性中的 Blob 名稱:

{
  "bindings": [
    {
      "queueName": "myqueue-items",
      "connection": "MyStorageConnectionAppSetting",
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in"
    },
    {
      "name": "myInputBlob",
      "type": "blob",
      "path": "samples-workitems/{queueTrigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in"
    },
    {
      "name": "myOutputBlob",
      "type": "blob",
      "path": "samples-workitems/{queueTrigger}-Copy",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "out"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

public static void Run(string myQueueItem, string myInputBlob, out string myOutputBlob, ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
    myOutputBlob = myInputBlob;
}

Blob 輸出

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 blob
direction 必須設定為 out
name 表示函式程式碼中 Blob 的變數名稱。
path blob 的路徑。
connection 指定 Azure Blob 連線方式的應用程式設定或設定集合的名稱。 請參閱連線

下列範例所示範的是使用繫結之 function.json 檔案,以及 C# 指令碼程式碼中的 Blob 輸入和輸出繫結。 此函式會建立文字 Blob 的複本。 此函式是由佇列訊息 (包含要複製的 Blob 名稱) 觸發。 新的 Blob 名稱為 {originalblobname}-Copy

function.json 檔案中,queueTrigger 中繼資料屬性用於指定 path 屬性中的 Blob 名稱:

{
  "bindings": [
    {
      "queueName": "myqueue-items",
      "connection": "MyStorageConnectionAppSetting",
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in"
    },
    {
      "name": "myInputBlob",
      "type": "blob",
      "path": "samples-workitems/{queueTrigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in"
    },
    {
      "name": "myOutputBlob",
      "type": "blob",
      "path": "samples-workitems/{queueTrigger}-Copy",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "out"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

public static void Run(string myQueueItem, string myInputBlob, out string myOutputBlob, ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
    myOutputBlob = myInputBlob;
}

RabbitMQ 觸發程序

下列範例示範 function.json 檔案中的 RabbitMQ 觸發程序繫結,以及使用此繫結的 C# 指令碼函式。 函式會讀取並記錄 RabbitMQ 訊息。

以下是 function.json 檔案中的繫結資料:

{​​
    "bindings": [
        {​​
            "name": "myQueueItem",
            "type": "rabbitMQTrigger",
            "direction": "in",
            "queueName": "queue",
            "connectionStringSetting": "rabbitMQConnectionAppSetting"
        }​​
    ]
}​​

以下是 C# 指令碼程式碼:

using System;

public static void Run(string myQueueItem, ILogger log)
{​​
    log.LogInformation($"C# Script RabbitMQ trigger function processed: {​​myQueueItem}​​");
}​​

佇列觸發程序

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 queueTrigger。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
direction 僅限在 function.json 檔案中。 必須設定為 in。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
name 在函式程式碼中包含佇列項目承載的變數名稱。
queueName 要輪詢的佇列名稱。
connection 應用程式設定或設定集合的名稱,其指定如何連線到 Azure 佇列。 請參閱連線

下列範例示範的是 function.json 檔案中的佇列觸發程序繫結,以及使用該繫結的 C# 指令碼程式碼。 此函式會輪詢 myqueue-items 佇列,並在每次處理佇列項目時寫入記錄。

以下是 function.json 檔案:

{
    "disabled": false,
    "bindings": [
        {
            "type": "queueTrigger",
            "direction": "in",
            "name": "myQueueItem",
            "queueName": "myqueue-items",
            "connection":"MyStorageConnectionAppSetting"
        }
    ]
}

以下是 C# 指令碼程式碼:

#r "Microsoft.WindowsAzure.Storage"

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

public static void Run(CloudQueueMessage myQueueItem, 
    DateTimeOffset expirationTime, 
    DateTimeOffset insertionTime, 
    DateTimeOffset nextVisibleTime,
    string queueTrigger,
    string id,
    string popReceipt,
    int dequeueCount,
    ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed: {myQueueItem.AsString}\n" +
        $"queueTrigger={queueTrigger}\n" +
        $"expirationTime={expirationTime}\n" +
        $"insertionTime={insertionTime}\n" +
        $"nextVisibleTime={nextVisibleTime}\n" +
        $"id={id}\n" +
        $"popReceipt={popReceipt}\n" + 
        $"dequeueCount={dequeueCount}");
}

佇列輸出

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 queue。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
direction 必須設定為 out。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
name 代表函式程式碼中佇列的變數名稱。 設為 $return 以參考函式傳回值。
queueName 佇列的名稱。
connection 應用程式設定或設定集合的名稱,其指定如何連線到 Azure 佇列。 請參閱連線

下列範例示範的是 function.json 檔案中的 HTTP 觸發程序繫結,以及使用該繫結的 C# 指令碼程式碼。 此函式會針對每個收到的 HTTP 要求,使用 CustomQueueMessage 物件承載來建立佇列項目。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "authLevel": "function",
      "name": "input"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "$return",
      "queueName": "outqueue",
      "connection": "MyStorageConnectionAppSetting"
    }
  ]
}

以下是建立單一佇列訊息的 C# 指令碼程式碼:

public class CustomQueueMessage
{
    public string PersonName { get; set; }
    public string Title { get; set; }
}

public static CustomQueueMessage Run(CustomQueueMessage input, ILogger log)
{
    return input;
}

您可以使用 ICollectorIAsyncCollector 參數一次傳送多個訊息。 以下 C# 指令碼程式碼會傳送多個訊息,一個使用 HTTP 要求資料,一個使用硬式編碼值:

public static void Run(
    CustomQueueMessage input, 
    ICollector<CustomQueueMessage> myQueueItems, 
    ILogger log)
{
    myQueueItems.Add(input);
    myQueueItems.Add(new CustomQueueMessage { PersonName = "You", Title = "None" });
}

資料表輸入

本節概述僅對延伸模組資料表 API 版本的支援。

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 table。 當您在 Azure 入口網站中建立繫結時,會自動設定此屬性。
direction 必須設定為 in。 當您在 Azure 入口網站中建立繫結時,會自動設定此屬性。
name 代表函式程式碼中的資料表或實體的變數名稱。
tableName 資料表的名稱。
partitionKey 選擇性。 要讀取之資料表實體的分割區索引鍵。
rowKey 選擇性。 要讀取之資料表實體的資料列索引鍵。 無法與 takefilter 搭配使用。
take 選擇性。 要傳回的實體數目上限。 無法與 rowKey 搭配使用。
filter 選擇性。 要從資料表傳回哪些實體的 OData 篩選條件運算式。 無法與 rowKey 搭配使用。
connection 指定如何連線到資料表服務的應用程式設定或設定集合名稱。 請參閱連線

下列範例所示範的是 function.json 檔案中的資料表輸入繫結,以及使用繫結之 C# 指令碼程式碼。 此函式會使用佇列觸發程序來讀取單一資料表列。

function.json 檔案會指定 partitionKeyrowKeyrowKey{queueTrigger} 指出資料列索引鍵來自佇列訊息字串。

{
  "bindings": [
    {
      "queueName": "myqueue-items",
      "connection": "MyStorageConnectionAppSetting",
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in"
    },
    {
      "name": "personEntity",
      "type": "table",
      "tableName": "Person",
      "partitionKey": "Test",
      "rowKey": "{queueTrigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

#r "Azure.Data.Tables"
using Microsoft.Extensions.Logging;
using Azure.Data.Tables;

public static void Run(string myQueueItem, Person personEntity, ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
    log.LogInformation($"Name in Person entity: {personEntity.Name}");
}

public class Person : ITableEntity
{
    public string Name { get; set; }

    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }
}

資料表輸出

本節概述僅對延伸模組資料表 API 版本的支援。

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 table。 當您在 Azure 入口網站中建立繫結時,會自動設定此屬性。
direction 必須設定為 out。 當您在 Azure 入口網站中建立繫結時,會自動設定此屬性。
name 函式程式碼中所使用的變數名稱,代表資料表或實體。 設為 $return 以參考函式傳回值。
tableName 要寫入之資料表的名稱。
partitionKey 要寫入之資料表實體的分割區索引鍵。
rowKey 要寫入之資料表實體的資料列索引鍵。
connection 指定如何連線到資料表服務的應用程式設定或設定集合名稱。 請參閱連線

下列範例所示範的是 function.json 檔案中的資料表輸出繫結,以及使用繫結之 C# 指令碼程式碼。 函式會寫入多個資料表實體。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "name": "input",
      "type": "manualTrigger",
      "direction": "in"
    },
    {
      "tableName": "Person",
      "connection": "MyStorageConnectionAppSetting",
      "name": "tableBinding",
      "type": "table",
      "direction": "out"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

public static void Run(string input, ICollector<Person> tableBinding, ILogger log)
{
    for (int i = 1; i < 10; i++)
        {
            log.LogInformation($"Adding Person entity {i}");
            tableBinding.Add(
                new Person() { 
                    PartitionKey = "Test", 
                    RowKey = i.ToString(), 
                    Name = "Name" + i.ToString() }
                );
        }

}

public class Person
{
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public string Name { get; set; }
}

計時器觸發程序

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 timerTrigger。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
direction 必須設定為 in。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
name 代表函式程式碼中計時器物件的變數名稱。
schedule CRON 運算式TimeSpan 值。 TimeSpan 只能用於 App Service 方案上執行的函式應用程式。 您可以將排程運算式放在應用程式設定中,並將此屬性設定為以 % 符號包裝的應用程式設定名稱,如此範例所示:"%ScheduleAppSetting%"。
runOnStartup 如果為 true,當執行階段啟動時,會叫用函式。 例如,當函式應用程式因無活動而處於閒置狀態後再甦醒時、 當函式應用程式因函式變更而重新啟動時,以及當函式應用程式相應放大時,執行階段便會啟動。請小心使用。runOnStartup 應該很少設定為 true,尤其是在生產環境中。
useMonitor 設定為 truefalse 以表示是否應該監視排程。 排程監視會使排程持續進行,以協助確保即使在函式應用程式執行個體重新啟動時,排程也能正確地持續運作。 如果未明確設定,則針對循環間隔大於或等於 1 分鐘的排程,預設值為 true。 若為每分鐘觸發超過一次的排程,預設值為 false

下列範例示範 function.json 檔案中的計時器觸發程序繫結,以及使用此繫結的 C# 指令碼函式。 此函式會寫入一項記錄,指出此函式引動過程是否由遺失的排程項目所造成。 TimerInfo 物件會傳遞至函數。

以下是 function.json 檔案中的繫結資料:

{
    "schedule": "0 */5 * * * *",
    "name": "myTimer",
    "type": "timerTrigger",
    "direction": "in"
}

以下是 C# 指令碼程式碼:

public static void Run(TimerInfo myTimer, ILogger log)
{
    if (myTimer.IsPastDue)
    {
        log.LogInformation("Timer is running late!");
    }
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}" );  
}

HTTP 觸發程序

下表說明您在 function.json 檔案中設定的觸發程序設定屬性:

function.json 屬性 描述
type 必要項目 - 必須設定為 httpTrigger
direction 必要項目 - 必須設定為 in
name 必要項目 - 函式程式碼中用於要求或要求主體的變數名稱。
authLevel 會判斷要求中必須存在哪些金鑰 (若有的話) 才能叫用函式。 如需支援的值,請參閱授權層級
方法 函數將回應的 HTTP 方法陣列。 如果未指定,函式將會回應所有的 HTTP 方法。 請參閱自訂 HTTP 端點
route 會定義路由範本,從而控制函式所要回應的要求 URL。 如果沒有提供任何值,預設值為 <functionname>。 如需詳細資訊,請參閱自訂 HTTP 端點
webHookType 只有針對 1.x 版執行階段才有支援。

會設定 HTTP 觸發程序作為指定提供者的 webhook 接收器。 如需支援的值,請參閱 WebHook 類型

下列範例示範 function.json 檔案中的觸發程序繫結,以及使用此繫結的 C# 指令碼函式。 函式會尋找 name 參數,其位於查詢字串或 HTTP 要求的主體。

以下是 function.json 檔案:

{
    "disabled": false,
    "bindings": [
        {
            "authLevel": "function",
            "name": "req",
            "type": "httpTrigger",
            "direction": "in",
            "methods": [
                "get",
                "post"
            ]
        },
        {
            "name": "$return",
            "type": "http",
            "direction": "out"
        }
    ]
}

以下是繫結至 HttpRequest 的 C# 指令碼:

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];
    
    string requestBody = String.Empty;
    using (StreamReader streamReader =  new  StreamReader(req.Body))
    {
        requestBody = await streamReader.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");
}

您可以繫結至自訂的物件,而不是 HttpRequest。 會從要求主體建立這個物件,並剖析成 JSON。 同樣地,類型可以傳遞至 HTTP 回應輸出繫結,並加以傳回作為狀態碼 200 的回應主體。

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

public static string Run(Person person, ILogger log)
{   
    return person.Name != null
        ? (ActionResult)new OkObjectResult($"Hello, {person.Name}")
        : new BadRequestObjectResult("Please pass an instance of Person.");
}

public class Person {
     public string Name {get; set;}
}

HTTP 輸出

下表說明您在 function.json 檔案中設定的繫結設定屬性。

屬性 描述
type 必須設定為 http
direction 必須設定為 out
name 函式程式碼中用於回應的變數名稱,或要使用傳回值的 $return

事件中樞觸發程序

下表說明您在 function.json 檔案中設定的觸發程序設定屬性:

function.json 屬性 描述
type 必須設定為 eventHubTrigger。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
direction 必須設定為 in。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
name 代表函式程式碼中事件項目的變數名稱。
eventHubName Functions 2.x 和更新版本。 事件中樞的名稱。 當事件中樞名稱也呈現於連接字串時,該值會在執行階段覆寫這個屬性。 可透過應用程式設定%eventHubName%參考。 在版本 1.x 中,這個屬性名為 path
consumerGroup 選擇性屬性,可設定用來訂閱中樞內事件的取用者群組。 如果省略,則會使用 $Default 取用者群組。
connection 應用程式設定或設定集合的名稱,指定如何連線到事件中樞。 請參閱連線

下列範例示範 function.json 檔案中的事件中樞觸發程序繫結,以及使用該繫結的 C# 指令碼函式。 此函式記錄事件中樞觸發程序的訊息本文。

下列範例顯示 Functions 執行階段版本 2.x 和更新版本的 function.json 檔案中的事件中樞繫結資料。

{
  "type": "eventHubTrigger",
  "name": "myEventHubMessage",
  "direction": "in",
  "eventHubName": "MyEventHub",
  "connection": "myEventHubReadConnectionAppSetting"
}

以下是 C# 指令碼程式碼:

using System;

public static void Run(string myEventHubMessage, TraceWriter log)
{
    log.Info($"C# function triggered to process a message: {myEventHubMessage}");
}

若要取得函式程式碼中事件中繼資料的存取權,請繫結至 EventData 物件。 您也可以在方法簽章中使用繫結運算式,以存取相同的屬性。 下列範例示範取得相同資料的兩種方式:

#r "Microsoft.Azure.EventHubs"

using System.Text;
using System;
using Microsoft.ServiceBus.Messaging;
using Microsoft.Azure.EventHubs;

public void Run(EventData myEventHubMessage,
    DateTime enqueuedTimeUtc,
    Int64 sequenceNumber,
    string offset,
    TraceWriter log)
{
    log.Info($"Event: {Encoding.UTF8.GetString(myEventHubMessage.Body)}");
    log.Info($"EnqueuedTimeUtc={myEventHubMessage.SystemProperties.EnqueuedTimeUtc}");
    log.Info($"SequenceNumber={myEventHubMessage.SystemProperties.SequenceNumber}");
    log.Info($"Offset={myEventHubMessage.SystemProperties.Offset}");

    // Metadata accessed by using binding expressions
    log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");
    log.Info($"SequenceNumber={sequenceNumber}");
    log.Info($"Offset={offset}");
}

若要以批次方式接收事件,請讓 stringEventData 成為陣列:

public static void Run(string[] eventHubMessages, TraceWriter log)
{
    foreach (var message in eventHubMessages)
    {
        log.Info($"C# function triggered to process a message: {message}");
    }
}

事件中樞輸出

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
type 必須設定為 eventHub
direction 必須設定為 out。 當您在 Azure 入口網站中建立繫結時,會自動設定此參數。
name 函式程式碼中所使用的變數名稱,代表事件。
eventHubName Functions 2.x 和更新版本。 事件中樞的名稱。 當事件中樞名稱也呈現於連接字串時,該值會在執行階段覆寫這個屬性。 Functions 1.x 中,此屬性名為 path
connection 應用程式設定或設定集合的名稱,指定如何連線到事件中樞。 若要深入了解,請參閱連線

下列範例示範 function.json 檔案中的事件中樞觸發程序繫結,以及使用此繫結的 C# 指令碼函式。 此函式會將訊息寫入事件中樞。

下列範例顯示 function.json 檔案中 Functions 執行時間版本 2.x 和更新版本的事件中樞繫結資料。

{
    "type": "eventHub",
    "name": "outputEventHubMessage",
    "eventHubName": "myeventhub",
    "connection": "MyEventHubSendAppSetting",
    "direction": "out"
}

以下是可建立一則訊息的 C# 指令碼程式碼:

using System;
using Microsoft.Extensions.Logging;

public static void Run(TimerInfo myTimer, out string outputEventHubMessage, ILogger log)
{
    String msg = $"TimerTriggerCSharp1 executed at: {DateTime.Now}";
    log.LogInformation(msg);   
    outputEventHubMessage = msg;
}

以下是可建立多則訊息的 C# 指令碼程式碼:

public static void Run(TimerInfo myTimer, ICollector<string> outputEventHubMessage, ILogger log)
{
    string message = $"Message created at: {DateTime.Now}";
    log.LogInformation(message);
    outputEventHubMessage.Add("1 " + message);
    outputEventHubMessage.Add("2 " + message);
}

事件方格觸發程序

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。 沒有要在 EventGridTrigger 屬性中設定的建構函式參數或屬性。

function.json 屬性 描述
type 必要項目 - 必須設定為 eventGridTrigger
direction 必要項目 - 必須設定為 in
name 必要項目 - 函式程式碼中用於接收事件資料之參數的變數名稱。

下列範例顯示 function.json 檔案中定義的事件方格觸發程序。

以下是 function.json 檔案中的繫結資料:

{
  "bindings": [
    {
      "type": "eventGridTrigger",
      "name": "eventGridEvent",
      "direction": "in"
    }
  ],
  "disabled": false
}

以下是使用 EventGridEvent 繫結參數的 C# 指令碼函式範例:

#r "Azure.Messaging.EventGrid"
using Azure.Messaging.EventGrid;
using Microsoft.Extensions.Logging;

public static void Run(EventGridEvent eventGridEvent, ILogger log)
{
    log.LogInformation(eventGridEvent.Data.ToString());
}

以下是使用 JObject 繫結參數的 C# 指令碼函式範例:

#r "Newtonsoft.Json"

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public static void Run(JObject eventGridEvent, TraceWriter log)
{
    log.Info(eventGridEvent.ToString(Formatting.Indented));
}

事件方格輸出

下表說明您在 function.json 檔案中針對 C# 指令碼設定的繫結組態屬性。

function.json 屬性 描述
type 必須設定為 eventGrid
direction 必須設定為 out。 當您在 Azure 入口網站中建立繫結時,會自動設定此參數。
name 函式程式碼中所使用的變數名稱,代表事件。
topicEndpointUri 應用程式設定的名稱,其中包含自訂主題的 URI,例如 MyTopicEndpointUri
topicKeySetting 應用程式設定的名稱,其中包含自訂主題的存取金鑰。

下列範例顯示 function.json 檔案中的事件方格輸出繫結資料。

{
    "type": "eventGrid",
    "name": "outputEvent",
    "topicEndpointUri": "MyEventGridTopicUriSetting",
    "topicKeySetting": "MyEventGridTopicKeySetting",
    "direction": "out"
}

以下是可建立一個事件的 C# 指令碼程式碼:

#r "Microsoft.Azure.EventGrid"
using System;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Extensions.Logging;

public static void Run(TimerInfo myTimer, out EventGridEvent outputEvent, ILogger log)
{
    outputEvent = new EventGridEvent("message-id", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0");
}

以下是可建立數個事件的 C# 指令碼程式碼:

#r "Microsoft.Azure.EventGrid"
using System;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Extensions.Logging;

public static void Run(TimerInfo myTimer, ICollector<EventGridEvent> outputEvent, ILogger log)
{
    outputEvent.Add(new EventGridEvent("message-id-1", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0"));
    outputEvent.Add(new EventGridEvent("message-id-2", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0"));
}

服務匯流排觸發程序

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
type 必須設定為 serviceBusTrigger。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
direction 必須設定為 in。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
name 代表函式程式碼中佇列或主題訊息的變數名稱。
queueName 要監視的佇列名稱。 只有在監視佇列時設定 (不適用於主題)。
topicName 要監視的主題名稱。 只有在監視主題時設定 (不適用於佇列)。
subscriptionName 要監視的訂用帳戶名稱。 只有在監視主題時設定 (不適用於佇列)。
connection 指定如何連線到服務匯流排的應用程式設定或設定集合名稱。 請參閱連線
accessRights 連接字串的存取權限。 可用值為 managelisten。 預設值是 manage,這表示 connection 已具備管理權限。 如果您使用沒有管理權限的連接字串,請將 accessRights 設定為 "listen"。 否則,Functions 執行階段在嘗試執行需要管理權限的作業時可能會失敗。 在 Azure Functions 版本 2.x 及以上版本中,無法使用此屬性,因為最新版的服務匯流排 SDK 不支援管理作業。
isSessionsEnabled 如果連接到工作階段感知佇列或訂用帳戶,則為 true。 否則為 false,其為預設值。
autoComplete 當觸發程序應在處理之後自動呼叫完成,或函式程式碼會手動呼叫完成時,其為 true

在 C# 中只支援設定為 false

如果設定為 true 且觸發程序在函式執行成功完成,那麼觸發程序會自動完成訊息,否則會放棄訊息。
<br/當設定為 false 時,您負責呼叫 ServiceBusReceiver 方法,以完成、放棄訊息、工作階段或批次,或使其無效化。 擲回例外狀況 (未呼叫任何 ServiceBusReceiver 方法) 時,鎖定會維持不變。 一旦鎖定到期,訊息就會以遞增的 DeliveryCount 重新排入佇列,並自動更新鎖定。

此屬性僅適用於 Azure Functions 2.x 和更新版本。

下列範例示範 function.json 檔案中的服務匯流排觸發程序繫結,以及使用此繫結的 C# 指令碼函式。 此函式可讀取訊息中繼資料和記錄服務匯流排佇列訊息。

以下是 function.json 檔案中的繫結資料:

{
"bindings": [
    {
    "queueName": "testqueue",
    "connection": "MyServiceBusConnection",
    "name": "myQueueItem",
    "type": "serviceBusTrigger",
    "direction": "in"
    }
],
"disabled": false
}

以下是 C# 指令碼程式碼:

using System;

public static void Run(string myQueueItem,
    Int32 deliveryCount,
    DateTime enqueuedTimeUtc,
    string messageId,
    TraceWriter log)
{
    log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");

    log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");
    log.Info($"DeliveryCount={deliveryCount}");
    log.Info($"MessageId={messageId}");
}

服務匯流排輸出

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
type 必須設定為 serviceBus。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
direction 必須設定為 out。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此屬性。
name 代表函式程式碼中佇列或主題訊息的變數名稱。 設為 "$return" 以參考函式傳回值。
queueName 待辦事項的名稱。 只有在傳送佇列訊息時設定 (不適用於主題)。
topicName 主題的名稱。 只有在傳送主題訊息時設定 (不適用於佇列)。
connection 指定如何連線到服務匯流排的應用程式設定或設定集合名稱。 請參閱連線
accessRights (僅限 v1) 連接字串的存取權限。 可用值為 managelisten。 預設值是 manage,這表示 connection 已具備管理權限。 如果您使用沒有管理權限的連接字串,請將 accessRights 設定為 "listen"。 否則,Functions 執行階段在嘗試執行需要管理權限的作業時可能會失敗。 在 Azure Functions 版本 2.x 及以上版本中,無法使用此屬性,因為最新版的服務匯流排 SDK 不支援管理作業。

下列範例示範 function.json 檔案中的服務匯流排輸出繫結,以及使用此繫結的 C# 指令碼函式。 此函式會使用計時器觸發程序,每隔 15 秒傳送一則佇列訊息。

以下是 function.json 檔案中的繫結資料:

{
    "bindings": [
        {
            "schedule": "0/15 * * * * *",
            "name": "myTimer",
            "runsOnStartup": true,
            "type": "timerTrigger",
            "direction": "in"
        },
        {
            "name": "outputSbQueue",
            "type": "serviceBus",
            "queueName": "testqueue",
            "connection": "MyServiceBusConnection",
            "direction": "out"
        }
    ],
    "disabled": false
}

以下是可建立單一訊息的 C# 指令碼程式碼:

public static void Run(TimerInfo myTimer, ILogger log, out string outputSbQueue)
{
    string message = $"Service Bus queue message created at: {DateTime.Now}";
    log.LogInformation(message); 
    outputSbQueue = message;
}

以下是可建立多則訊息的 C# 指令碼程式碼:

public static async Task Run(TimerInfo myTimer, ILogger log, IAsyncCollector<string> outputSbQueue)
{
    string message = $"Service Bus queue messages created at: {DateTime.Now}";
    log.LogInformation(message); 
    await outputSbQueue.AddAsync("1 " + message);
    await outputSbQueue.AddAsync("2 " + message);
}

Azure Cosmos DB v2 觸發程序

本節僅概述對延伸模組 4.x+ 版本的支援。

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
type 必須設定為 cosmosDBTrigger
direction 必須設定為 in。 當您在 Azure 入口網站中建立觸發程序時,會自動設定此參數。
name 函式程式碼中使用的變數名稱,代表有變更的文件清單。
connection 應用程式設定或設定集合的名稱,該名稱會指定如何連接到要監視的 Azure Cosmos DB 帳戶。 如需詳細資訊,請參閱連線
databaseName 該 Azure Cosmos DB 資料庫名稱含有要監視的容器。
containerName 要監視的容器名稱。
leaseConnection (選擇性) 應用程式設定或設定容器的名稱,該名稱會指定如何連接到保存租用容器的 Azure Cosmos DB 帳戶。

如果未設定,會使用 connection 值。 在入口網站中建立繫結時,會自動設定此參數。 租用容器的連接字串必須具有寫入權限。
leaseDatabaseName (選擇性) 保存租用儲存容器的資料庫名稱。 如果未設定,會使用 databaseName 設定的值。
leaseContainerName (選擇性) 用來儲存租用的容器名稱。 如果未設定,會使用 leases 值。
createLeaseContainerIfNotExists (選擇性) 設為 true 時,如果租用容器尚未存在,即會自動加以建立。 預設值是 false。 使用 Microsoft Entra 身分識別時,如果您將值設定為 true,則建立容器是不允許的作業,函式也將無法啟動。
leasesContainerThroughput (選擇性) 定義要在建立租用容器時指派的要求單位數。 只有在將 createLeaseContainerIfNotExists 設為 true 時才會使用此設定。 使用入口網站建立繫結時,會自動設定此參數。
leaseContainerPrefix (選擇性) 設定時,系統會將值新增為此函式租用容器中建立的租用前置詞。 使用前置詞可讓兩個個別 Azure Functions 透過不同的前置詞,來共用相同的租用容器。
feedPollDelay (選擇性) 在目前所有的變更都清空後,每次輪詢分割區以了解摘要上是否有新變更時所要延遲的時間 (以毫秒為單位)。 預設值為 5,000 毫秒或 5 秒。
leaseAcquireInterval (選擇性) 如果設定,將會以毫秒為單位定義啟動工作以計算分割區是否平均分散到已知主機執行個體的間隔。 預設值為 13000 (13 秒)。
leaseExpirationInterval (選擇性) 如果設定,將會以毫秒為單位定義租用代表分割區的間隔。 未在此間隔內更新的租用將會過期,且分割區的擁有權會移轉給另一個執行個體。 預設值為 60000 (60 秒)。
leaseRenewInterval (選擇性) 如果設定,將會以毫秒為單位定義目前由執行個體保有之分割區的所有租用所適用的更新間隔。 預設值為 17000 (17 秒)。
maxItemsPerInvocation (選擇性) 如果設定,此屬性會設定每個函式呼叫可收到的項目數上限。 如果受監視容器中的作業是透過預存程序執行,那麼從變更摘要讀取項目時會保留異動範圍。 如此一來,所接收的項目數可能會高於指定的值,這樣同一次異動所變更的項目,就會在一個不可部分完成的批次中傳回。
startFromBeginning (選擇性) 此選項會告知觸發程序從容器的變更歷程記錄開頭讀取變更,而非當前的時間開頭。 因為在後續執行中,檢查點已儲存,所以從開頭讀取僅適用於觸發程序第一次啟動的情況下。 若已經建立租用,則將此選項設為 true 不會有任何作用。
startFromTime (選擇性) 取得或設定要初始化變更摘要讀取作業的開始日期和時間。 建議的格式是 ISO 8601 包含 UTC 指示項,例如 2021-02-16T14:19:29Z。 此項目僅用於設定初始觸發程序狀態。 一旦觸發程序具有租用狀態之後,變更此值不會有任何作用。
preferredLocations (選用) 定義 Azure Cosmos DB 服務中異地複寫資料庫帳戶的慣用位置 (區域)。 應該以逗號將值分隔。 例如,"East US,South Central US,North Europe"。

下列範例顯示 function.json 檔案中的 Azure Cosmos DB 觸發繫結,以及使用此繫結的 C# 指令碼函式。 新增或修改 Azure Cosmos DB 記錄時,函式會寫入記錄訊息。

以下是 function.json 檔案中的繫結資料:

{
    "type": "cosmosDBTrigger",
    "name": "documents",
    "direction": "in",
    "leaseContainerName": "leases",
    "connection": "<connection-app-setting>",
    "databaseName": "Tasks",
    "containerName": "Items",
    "createLeaseContainerIfNotExists": true
}

以下是 C# 指令碼程式碼:

    using System;
    using System.Collections.Generic;
    using Microsoft.Extensions.Logging;

    // Customize the model with your own desired properties
    public class ToDoItem
    {
        public string id { get; set; }
        public string Description { get; set; }
    }

    public static void Run(IReadOnlyList<ToDoItem> documents, ILogger log)
    {
      log.LogInformation("Documents modified " + documents.Count);
      log.LogInformation("First document Id " + documents[0].id);
    }

Azure Cosmos DB v2 輸入

本節僅概述對延伸模組 4.x+ 版本的支援。

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
type 必須設定為 cosmosDB
direction 必須設定為 in
name 函式程式碼中使用的變數名稱,代表有變更的文件清單。
connection 應用程式設定或設定容器的名稱,該名稱會指定如何連接到要監視的 Azure Cosmos DB 帳戶。 如需詳細資訊,請參閱連線
databaseName 該 Azure Cosmos DB 資料庫名稱含有要監視的容器。
containerName 要監視的容器名稱。
partitionKey 指定分割區索引鍵值進行查閱。 可能包含繫結參數。 資料分割容器中的查閱是必要的。
id 要擷取之文件的識別碼。 此屬性支援繫結運算式。 請勿同時設定 idsqlQuery 屬性。 如果您未設定其中一個,就會擷取整個容器。
sqlQuery 用來擷取多份文件的 Azure Cosmos DB SQL 查詢。 屬性會支援執行階段繫結,如此範例所示:SELECT * FROM c where c.departmentId = {departmentId}。 請勿同時設定 idsqlQuery 屬性。 如果您未設定其中一個,就會擷取整個容器。
preferredLocations (選用) 定義 Azure Cosmos DB 服務中異地複寫資料庫帳戶的慣用位置 (區域)。 應該以逗號將值分隔。 例如: East US,South Central US,North Europe

本區段包含下列範例:

HTTP 觸發程序範例會參考簡單的 ToDoItem 類型:

namespace CosmosDBSamplesV2
{
    public class ToDoItem
    {
        public string Id { get; set; }
        public string Description { get; set; }
    }
}

佇列觸發程序,從字串中查閱識別碼

下列範例顯示 function.json 檔案中的 Azure Cosmos DB 輸入繫結,以及使用此繫結的 C# 指令碼函式。 函式會讀取單一文件,並更新文件的文字值。

以下是 function.json 檔案中的繫結資料:

{
    "name": "inputDocument",
    "type": "cosmosDB",
    "databaseName": "MyDatabase",
    "collectionName": "MyCollection",
    "id" : "{queueTrigger}",
    "partitionKey": "{partition key value}",
    "connectionStringSetting": "MyAccount_COSMOSDB",
    "direction": "in"
}

以下是 C# 指令碼程式碼:

    using System;

    // Change input document contents using Azure Cosmos DB input binding
    public static void Run(string myQueueItem, dynamic inputDocument)
    {
      inputDocument.text = "This has changed.";
    }

佇列觸發程序,使用 SqlQuery 取得多個文件

下列範例顯示 function.json 檔案中的 Azure Cosmos DB 輸入繫結,以及使用此繫結的 C# 指令碼函式。 函式會使用佇列觸發程序來自訂查詢參數,以擷取 SQL 查詢所指定的多份文件。

佇列觸發程序會提供參數 departmentId{ "departmentId" : "Finance" } 的佇列訊息會傳回財務部門的所有記錄。

以下是 function.json 檔案中的繫結資料:

{
    "name": "documents",
    "type": "cosmosDB",
    "direction": "in",
    "databaseName": "MyDb",
    "collectionName": "MyCollection",
    "sqlQuery": "SELECT * from c where c.departmentId = {departmentId}",
    "connectionStringSetting": "CosmosDBConnection"
}

以下是 C# 指令碼程式碼:

    public static void Run(QueuePayload myQueueItem, IEnumerable<dynamic> documents)
    {
        foreach (var doc in documents)
        {
            // operate on each document
        }
    }

    public class QueuePayload
    {
        public string departmentId { get; set; }
    }

HTTP 觸發程序,從查詢字串中查閱識別碼

下列範例會顯示擷取單一文件的 C# 指令碼函式。 函式會由 HTTP 要求觸發,該 HTTP 要求會使用查詢字串指定要查閱的識別碼和分割區索引鍵值。 該識別碼和分割區索引鍵值會用來從指定的資料庫和集合中擷取 ToDoItem 文件。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "cosmosDB",
      "name": "toDoItem",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connectionStringSetting": "CosmosDBConnection",
      "direction": "in",
      "Id": "{Query.id}",
      "PartitionKey" : "{Query.partitionKeyValue}"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

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

public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    if (toDoItem == null)
    {
         log.LogInformation($"ToDo item not found");
    }
    else
    {
        log.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

HTTP 觸發程序,從路由資料中查閱識別碼

下列範例會顯示擷取單一文件的 C# 指令碼函式。 函式會由 HTTP 要求觸發,該 HTTP 要求會使用路由資料指定要查閱的識別碼和分割區索引鍵值。 該識別碼和分割區索引鍵值會用來從指定的資料庫和集合中擷取 ToDoItem 文件。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ],
      "route":"todoitems/{partitionKeyValue}/{id}"
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "cosmosDB",
      "name": "toDoItem",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connectionStringSetting": "CosmosDBConnection",
      "direction": "in",
      "id": "{id}",
      "partitionKey": "{partitionKeyValue}"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

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

public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    if (toDoItem == null)
    {
         log.LogInformation($"ToDo item not found");
    }
    else
    {
        log.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

HTTP 觸發程序,使用 SqlQuery 取得多個文件

下列範例會顯示擷取文件清單的 C# 指令碼函數。 函式是由 HTTP 要求所觸發。 查詢會在 SqlQuery 屬性內容中指定。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "cosmosDB",
      "name": "toDoItems",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connectionStringSetting": "CosmosDBConnection",
      "direction": "in",
      "sqlQuery": "SELECT top 2 * FROM c order by c._ts desc"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

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

public static HttpResponseMessage Run(HttpRequestMessage req, IEnumerable<ToDoItem> toDoItems, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    foreach (ToDoItem toDoItem in toDoItems)
    {
        log.LogInformation(toDoItem.Description);
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

HTTP 觸發程序,使用 DocumentClient 取得多個文件

下列範例會顯示擷取文件清單的 C# 指令碼函數。 函式是由 HTTP 要求所觸發。 程式碼會使用由 Azure Cosmos DB 繫結提供的 DocumentClient 執行個體來讀取文件清單。 DocumentClient 執行個體也會用來進行寫入作業。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "cosmosDB",
      "name": "client",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connectionStringSetting": "CosmosDBConnection",
      "direction": "inout"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

#r "Microsoft.Azure.Documents.Client"

using System.Net;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Microsoft.Extensions.Logging;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, DocumentClient client, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    Uri collectionUri = UriFactory.CreateDocumentCollectionUri("ToDoItems", "Items");
    string searchterm = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "searchterm", true) == 0)
        .Value;

    if (searchterm == null)
    {
        return req.CreateResponse(HttpStatusCode.NotFound);
    }

    log.LogInformation($"Searching for word: {searchterm} using Uri: {collectionUri.ToString()}");
    IDocumentQuery<ToDoItem> query = client.CreateDocumentQuery<ToDoItem>(collectionUri)
        .Where(p => p.Description.Contains(searchterm))
        .AsDocumentQuery();

    while (query.HasMoreResults)
    {
        foreach (ToDoItem result in await query.ExecuteNextAsync())
        {
            log.LogInformation(result.Description);
        }
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

Azure Cosmos DB v2 輸出

本節僅概述對延伸模組 4.x+ 版本的支援。

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
connection 應用程式設定或設定集合的名稱,該名稱會指定如何連接到要監視的 Azure Cosmos DB 帳戶。 如需詳細資訊,請參閱連線
databaseName 該 Azure Cosmos DB 資料庫名稱含有要監視的容器。
containerName 要監視的容器名稱。
createIfNotExists 一個布林值,用來指出當容器不存在時,是否要建立集合。 預設是 false,因為新容器建立時會保留輸送量,對成本可能會有所影響。 如需詳細資訊,請參閱價格網頁
partitionKey createIfNotExists 為 true 時,它會定義所建立容器的分割區金鑰路徑。 可能包含繫結參數。
containerThroughput createIfNotExists 為 true 時,它會定義所建立容器的輸送量
preferredLocations (選用) 定義 Azure Cosmos DB 服務中異地複寫資料庫帳戶的慣用位置 (區域)。 應該以逗號將值分隔。 例如: East US,South Central US,North Europe

本區段包含下列範例:

佇列觸發程序,寫入一份文件

下列範例顯示 function.json 檔案中的 Azure Cosmos DB 輸出繫結,以及使用此繫結的 C# 指令碼函式。 此函式會使用可接收 JSON 佇列的佇列輸入繫結,其格式如下︰

{
    "name": "John Henry",
    "employeeId": "123456",
    "address": "A town nearby"
}

此函式會針對每一筆記錄建立下列格式的 Azure Cosmos DB 文件:

{
    "id": "John Henry-123456",
    "name": "John Henry",
    "employeeId": "123456",
    "address": "A town nearby"
}

以下是 function.json 檔案中的繫結資料:

{
    "name": "employeeDocument",
    "type": "cosmosDB",
    "databaseName": "MyDatabase",
    "collectionName": "MyCollection",
    "createIfNotExists": true,
    "connectionStringSetting": "MyAccount_COSMOSDB",
    "direction": "out"
}

以下是 C# 指令碼程式碼:

    #r "Newtonsoft.Json"

    using Microsoft.Azure.WebJobs.Host;
    using Newtonsoft.Json.Linq;
    using Microsoft.Extensions.Logging;

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

      dynamic employee = JObject.Parse(myQueueItem);

      employeeDocument = new {
        id = employee.name + "-" + employee.employeeId,
        name = employee.name,
        employeeId = employee.employeeId,
        address = employee.address
      };
    }

佇列觸發程序,使用 IAsyncCollector 寫入文件

如果要建立多個文件,您可以繫結至 ICollector<T>IAsyncCollector<T>T 表示其中一種支援的類型。

此範例會參考簡單的 ToDoItem 類型:

namespace CosmosDBSamplesV2
{
    public class ToDoItem
    {
        public string id { get; set; }
        public string Description { get; set; }
    }
}

以下是 function.json 檔案:

{
  "bindings": [
    {
      "name": "toDoItemsIn",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "todoqueueforwritemulti",
      "connectionStringSetting": "AzureWebJobsStorage"
    },
    {
      "type": "cosmosDB",
      "name": "toDoItemsOut",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connectionStringSetting": "CosmosDBConnection",
      "direction": "out"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

using System;
using Microsoft.Extensions.Logging;

public static async Task Run(ToDoItem[] toDoItemsIn, IAsyncCollector<ToDoItem> toDoItemsOut, ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed {toDoItemsIn?.Length} items");

    foreach (ToDoItem toDoItem in toDoItemsIn)
    {
        log.LogInformation($"Description={toDoItem.Description}");
        await toDoItemsOut.AddAsync(toDoItem);
    }
}

Azure Cosmos DB v1 觸發程序

下列範例顯示 function.json 檔案中的 Azure Cosmos DB 觸發繫結,以及使用此繫結的 C# 指令碼函式。 修改 Azure Cosmos DB 記錄時,函式會寫入記錄訊息。

以下是 function.json 檔案中的繫結資料:

{
    "type": "cosmosDBTrigger",
    "name": "documents",
    "direction": "in",
    "leaseCollectionName": "leases",
    "connectionStringSetting": "<connection-app-setting>",
    "databaseName": "Tasks",
    "collectionName": "Items",
    "createLeaseCollectionIfNotExists": true
}

以下是 C# 指令碼程式碼:

    #r "Microsoft.Azure.Documents.Client"
    
    using System;
    using Microsoft.Azure.Documents;
    using System.Collections.Generic;
    

    public static void Run(IReadOnlyList<Document> documents, TraceWriter log)
    {
        log.Info("Documents modified " + documents.Count);
        log.Info("First document Id " + documents[0].Id);
    }

Azure Cosmos DB v1 輸入

本區段包含下列範例:

HTTP 觸發程序範例會參考簡單的 ToDoItem 類型:

namespace CosmosDBSamplesV1
{
    public class ToDoItem
    {
        public string Id { get; set; }
        public string Description { get; set; }
    }
}

佇列觸發程序,從字串中查閱識別碼

下列範例顯示 function.json 檔案中的 Azure Cosmos DB 輸入繫結,以及使用此繫結的 C# 指令碼函式。 函式會讀取單一文件,並更新文件的文字值。

以下是 function.json 檔案中的繫結資料:

{
    "name": "inputDocument",
    "type": "documentDB",
    "databaseName": "MyDatabase",
    "collectionName": "MyCollection",
    "id" : "{queueTrigger}",
    "partitionKey": "{partition key value}",
    "connection": "MyAccount_COSMOSDB",
    "direction": "in"
}

以下是 C# 指令碼程式碼:

    using System;

    // Change input document contents using Azure Cosmos DB input binding
    public static void Run(string myQueueItem, dynamic inputDocument)
    {
        inputDocument.text = "This has changed.";
    }

佇列觸發程序,使用 SqlQuery 取得多個文件

下列範例顯示 function.json 檔案中的 Azure Cosmos DB 輸入繫結,以及使用此繫結的 C# 指令碼函式。 函式會使用佇列觸發程序來自訂查詢參數,以擷取 SQL 查詢所指定的多份文件。

佇列觸發程序會提供參數 departmentId{ "departmentId" : "Finance" } 的佇列訊息會傳回財務部門的所有記錄。

以下是 function.json 檔案中的繫結資料:

{
    "name": "documents",
    "type": "documentdb",
    "direction": "in",
    "databaseName": "MyDb",
    "collectionName": "MyCollection",
    "sqlQuery": "SELECT * from c where c.departmentId = {departmentId}",
    "connection": "CosmosDBConnection"
}

以下是 C# 指令碼程式碼:

    public static void Run(QueuePayload myQueueItem, IEnumerable<dynamic> documents)
    {
        foreach (var doc in documents)
        {
            // operate on each document
        }
    }

    public class QueuePayload
    {
        public string departmentId { get; set; }
    }

HTTP 觸發程序,從查詢字串中查閱識別碼

下列範例會顯示擷取單一文件的 C# 指令碼函式。 函式會由 HTTP 要求觸發,該 HTTP 要求會使用查詢字串指定要查閱的識別碼。 該識別碼會用來從指定的資料庫和集合中,擷取 ToDoItem 文件。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "documentDB",
      "name": "toDoItem",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connection": "CosmosDBConnection",
      "direction": "in",
      "Id": "{Query.id}"
    }
  ],
  "disabled": true
}

以下是 C# 指令碼程式碼:

using System.Net;

public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    if (toDoItem == null)
    {
        log.Info($"ToDo item not found");
    }
    else
    {
        log.Info($"Found ToDo item, Description={toDoItem.Description}");
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

HTTP 觸發程序,從路由資料中查閱識別碼

下列範例會顯示擷取單一文件的 C# 指令碼函式。 函式會由 HTTP 要求觸發,該 HTTP 要求會使用路由資料指定要查閱的識別碼。 該識別碼會用來從指定的資料庫和集合中,擷取 ToDoItem 文件。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ],
      "route":"todoitems/{id}"
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "documentDB",
      "name": "toDoItem",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connection": "CosmosDBConnection",
      "direction": "in",
      "Id": "{id}"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

using System.Net;

public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    if (toDoItem == null)
    {
        log.Info($"ToDo item not found");
    }
    else
    {
        log.Info($"Found ToDo item, Description={toDoItem.Description}");
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

HTTP 觸發程序,使用 SqlQuery 取得多個文件

下列範例會顯示擷取文件清單的 C# 指令碼函式。 函式是由 HTTP 要求所觸發。 查詢會在 SqlQuery 屬性內容中指定。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "documentDB",
      "name": "toDoItems",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connection": "CosmosDBConnection",
      "direction": "in",
      "sqlQuery": "SELECT top 2 * FROM c order by c._ts desc"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

using System.Net;

public static HttpResponseMessage Run(HttpRequestMessage req, IEnumerable<ToDoItem> toDoItems, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    foreach (ToDoItem toDoItem in toDoItems)
    {
        log.Info(toDoItem.Description);
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

HTTP 觸發程序,使用 DocumentClient 取得多個文件

下列範例會顯示擷取文件清單的 C# 指令碼函式。 函式是由 HTTP 要求所觸發。 程式碼會使用由 Azure Cosmos DB 繫結提供的 DocumentClient 執行個體來讀取文件清單。 DocumentClient 執行個體也會用來進行寫入作業。

以下是 function.json 檔案:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "documentDB",
      "name": "client",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connection": "CosmosDBConnection",
      "direction": "inout"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

#r "Microsoft.Azure.Documents.Client"

using System.Net;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, DocumentClient client, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    Uri collectionUri = UriFactory.CreateDocumentCollectionUri("ToDoItems", "Items");
    string searchterm = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "searchterm", true) == 0)
        .Value;

    if (searchterm == null)
    {
        return req.CreateResponse(HttpStatusCode.NotFound);
    }

    log.Info($"Searching for word: {searchterm} using Uri: {collectionUri.ToString()}");
    IDocumentQuery<ToDoItem> query = client.CreateDocumentQuery<ToDoItem>(collectionUri)
        .Where(p => p.Description.Contains(searchterm))
        .AsDocumentQuery();

    while (query.HasMoreResults)
    {
        foreach (ToDoItem result in await query.ExecuteNextAsync())
        {
            log.Info(result.Description);
        }
    }
    return req.CreateResponse(HttpStatusCode.OK);
}

Azure Cosmos DB v1 輸出

本區段包含下列範例:

  • 佇列觸發程序,寫入一份文件
  • 佇列觸發程序,使用 IAsyncCollector 寫入文件

佇列觸發程序,寫入一份文件

下列範例顯示 function.json 檔案中的 Azure Cosmos DB 輸出繫結,以及使用此繫結的 C# 指令碼函式。 此函式會使用可接收 JSON 佇列的佇列輸入繫結,其格式如下︰

{
    "name": "John Henry",
    "employeeId": "123456",
    "address": "A town nearby"
}

此函式會針對每一筆記錄建立下列格式的 Azure Cosmos DB 文件:

{
    "id": "John Henry-123456",
    "name": "John Henry",
    "employeeId": "123456",
    "address": "A town nearby"
}

以下是 function.json 檔案中的繫結資料:

{
    "name": "employeeDocument",
    "type": "documentDB",
    "databaseName": "MyDatabase",
    "collectionName": "MyCollection",
    "createIfNotExists": true,
    "connection": "MyAccount_COSMOSDB",
    "direction": "out"
}

以下是 C# 指令碼程式碼:

    #r "Newtonsoft.Json"

    using Microsoft.Azure.WebJobs.Host;
    using Newtonsoft.Json.Linq;

    public static void Run(string myQueueItem, out object employeeDocument, TraceWriter log)
    {
        log.Info($"C# Queue trigger function processed: {myQueueItem}");

        dynamic employee = JObject.Parse(myQueueItem);

        employeeDocument = new {
            id = employee.name + "-" + employee.employeeId,
            name = employee.name,
            employeeId = employee.employeeId,
            address = employee.address
        };
    }

佇列觸發程序,使用 IAsyncCollector 寫入文件

如果要建立多個文件,您可以繫結至 ICollector<T>IAsyncCollector<T>T 表示其中一種支援的類型。

此範例會參考簡單的 ToDoItem 類型:

namespace CosmosDBSamplesV1
{
    public class ToDoItem
    {
        public string Id { get; set; }
        public string Description { get; set; }
    }
}

以下是 function.json 檔案:

{
  "bindings": [
    {
      "name": "toDoItemsIn",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "todoqueueforwritemulti",
      "connection": "AzureWebJobsStorage"
    },
    {
      "type": "documentDB",
      "name": "toDoItemsOut",
      "databaseName": "ToDoItems",
      "collectionName": "Items",
      "connection": "CosmosDBConnection",
      "direction": "out"
    }
  ],
  "disabled": false
}

以下是 C# 指令碼程式碼:

using System;

public static async Task Run(ToDoItem[] toDoItemsIn, IAsyncCollector<ToDoItem> toDoItemsOut, TraceWriter log)
{
    log.Info($"C# Queue trigger function processed {toDoItemsIn?.Length} items");

    foreach (ToDoItem toDoItem in toDoItemsIn)
    {
        log.Info($"Description={toDoItem.Description}");
        await toDoItemsOut.AddAsync(toDoItem);
    }
}

Azure SQL 觸發程序

GitHub 存放庫中可取得 Azure SQL 觸發程序的其他範例。

這些範例會參考 ToDoItem 類別和對應的資料庫資料表:

namespace AzureSQL.ToDo
{
    public class ToDoItem
    {
        public Guid Id { get; set; }
        public int? order { get; set; }
        public string title { get; set; }
        public string url { get; set; }
        public bool? completed { get; set; }
    }
}
CREATE TABLE dbo.ToDo (
    [Id] UNIQUEIDENTIFIER PRIMARY KEY,
    [order] INT NULL,
    [title] NVARCHAR(200) NOT NULL,
    [url] NVARCHAR(200) NOT NULL,
    [completed] BIT NOT NULL
);

資料庫和資料表上已啟用變更追蹤

ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);

ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;

SQL 觸發程序會繫結至 IReadOnlyList<SqlChange<T>>,這是各有兩個屬性的 SqlChange 物件清單:

  • 項目:已變更的項目。 項目的類型應遵循 ToDoItem 類別中所見的資料表結構描述。
  • 作業:SqlChangeOperation 列舉中的值。 可能的值為:InsertUpdateDelete

以下範例顯示 function.json 檔案中的 SQL 觸發程序,以及在 ToDo 資料表發生變更時叫用的 C# 指令碼函式

以下是 function.json 檔案中的繫結資料:

{
    "name": "todoChanges",
    "type": "sqlTrigger",
    "direction": "in",
    "tableName": "dbo.ToDo",
    "connectionStringSetting": "SqlConnectionString"
}

以下是 C# 指令碼函式:

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static void Run(IReadOnlyList<SqlChange<ToDoItem>> todoChanges, ILogger log)
{
    log.LogInformation($"C# SQL trigger function processed a request.");

    foreach (SqlChange<ToDoItem> change in todoChanges)
    {
        ToDoItem toDoItem = change.Item;
        log.LogInformation($"Change operation: {change.Operation}");
        log.LogInformation($"Id: {toDoItem.Id}, Title: {toDoItem.title}, Url: {toDoItem.url}, Completed: {toDoItem.completed}");
    }
}

Azure SQL 輸入

Azure SQL 輸入繫結的其他範例可在 GitHub 存放庫中取得。

本區段包含下列範例:

這些範例會參考 ToDoItem 類別和對應的資料庫資料表:

namespace AzureSQL.ToDo
{
    public class ToDoItem
    {
        public Guid Id { get; set; }
        public int? order { get; set; }
        public string title { get; set; }
        public string url { get; set; }
        public bool? completed { get; set; }
    }
}
CREATE TABLE dbo.ToDo (
    [Id] UNIQUEIDENTIFIER PRIMARY KEY,
    [order] INT NULL,
    [title] NVARCHAR(200) NOT NULL,
    [url] NVARCHAR(200) NOT NULL,
    [completed] BIT NOT NULL
);

HTTP 觸發程序,依識別碼從查詢字串取得資料列

下列範例顯示 function.json 檔案中的 Azure SQL 輸入繫結,以及使用此繫結的 C# 指令碼函式。 此函式是由 HTTP 要求觸發,而該 HTTP 要求會使用查詢字串指定識別碼。 該識別碼用來擷取具有所指定查詢的 ToDoItem 記錄。

注意

HTTP 查詢字串參數會區分大小寫。

以下是 function.json 檔案中的繫結資料:

{
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
        "get"
    ]
},
{
    "type": "http",
    "direction": "out",
    "name": "res"
},
{
    "name": "todoItem",
    "type": "sql",
    "direction": "in",
    "commandText": "select [Id], [order], [title], [url], [completed] from dbo.ToDo where Id = @Id",
    "commandType": "Text",
    "parameters": "@Id = {Query.id}",
    "connectionStringSetting": "SqlConnectionString"
}

以下是 C# 指令碼程式碼:

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Collections.Generic;

public static IActionResult Run(HttpRequest req, ILogger log, IEnumerable<ToDoItem> todoItem)
{
    return new OkObjectResult(todoItem);
}

HTTP 觸發程序,刪除資料列

下列範例會顯示 function.json 檔案中的 Azure SQL 輸入繫結,以及使用此繫結的 C# 指令碼函式,以透過 HTTP 要求查詢參數中的輸入來執行預存程序。 在此範例中,預存程式會刪除單一記錄或所有記錄,取決於參數的值。

必須在 SQL 資料庫上建立預存程式 dbo.DeleteToDo

CREATE PROCEDURE [dbo].[DeleteToDo]
    @Id NVARCHAR(100)
AS
    DECLARE @UID UNIQUEIDENTIFIER = TRY_CAST(@ID AS UNIQUEIDENTIFIER)
    IF @UId IS NOT NULL AND @Id != ''
    BEGIN
        DELETE FROM dbo.ToDo WHERE Id = @UID
    END
    ELSE
    BEGIN
        DELETE FROM dbo.ToDo WHERE @ID = ''
    END

    SELECT [Id], [order], [title], [url], [completed] FROM dbo.ToDo
GO

以下是 function.json 檔案中的繫結資料:

{
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
        "get"
    ]
},
{
    "type": "http",
    "direction": "out",
    "name": "res"
},
{
    "name": "todoItems",
    "type": "sql",
    "direction": "in",
    "commandText": "DeleteToDo",
    "commandType": "StoredProcedure",
    "parameters": "@Id = {Query.id}",
    "connectionStringSetting": "SqlConnectionString"
}
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace AzureSQL.ToDo
{
    public static class DeleteToDo
    {
        // delete all items or a specific item from querystring
        // returns remaining items
        // uses input binding with a stored procedure DeleteToDo to delete items and return remaining items
        [FunctionName("DeleteToDo")]
        public static IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = "DeleteFunction")] HttpRequest req,
            ILogger log,
            [Sql(commandText: "DeleteToDo", commandType: System.Data.CommandType.StoredProcedure, 
                parameters: "@Id={Query.id}", connectionStringSetting: "SqlConnectionString")] 
                IEnumerable<ToDoItem> toDoItems)
        {
            return new OkObjectResult(toDoItems);
        }
    }
}

以下是 C# 指令碼程式碼:

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Collections.Generic;

public static IActionResult Run(HttpRequest req, ILogger log, IEnumerable<ToDoItem> todoItems)
{
    return new OkObjectResult(todoItems);
}

Azure SQL 輸出

Azure SQL 輸出繫結的其他範例可在 GitHub 存放庫中取得。

本區段包含下列範例:

這些範例會參考 ToDoItem 類別和對應的資料庫資料表:

namespace AzureSQL.ToDo
{
    public class ToDoItem
    {
        public Guid Id { get; set; }
        public int? order { get; set; }
        public string title { get; set; }
        public string url { get; set; }
        public bool? completed { get; set; }
    }
}
CREATE TABLE dbo.ToDo (
    [Id] UNIQUEIDENTIFIER PRIMARY KEY,
    [order] INT NULL,
    [title] NVARCHAR(200) NOT NULL,
    [url] NVARCHAR(200) NOT NULL,
    [completed] BIT NOT NULL
);

HTTP 觸發程序,將記錄寫入至資料表

下面範例會示範 function.json 檔案中的 SQL 輸出繫結,以及運用 HTTP POST 要求中提供的資料作為 JSON 主體,將記錄新增至資料表的 C# 指令碼函式

以下是 function.json 檔案中的繫結資料:

{
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
        "post"
    ]
},
{
    "type": "http",
    "direction": "out",
    "name": "res"
},
{
    "name": "todoItem",
    "type": "sql",
    "direction": "out",
    "commandText": "dbo.ToDo",
    "connectionStringSetting": "SqlConnectionString"
}

以下是 C# 指令碼程式碼範例:

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static IActionResult Run(HttpRequest req, ILogger log, out ToDoItem todoItem)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string requestBody = new StreamReader(req.Body).ReadToEnd();
    todoItem = JsonConvert.DeserializeObject<ToDoItem>(requestBody);

    return new OkObjectResult(todoItem);
}

HTTP 觸發程序,寫入至兩個資料表

下面範例會顯示 function.json 檔案的 SQL 輸出繫結,以及運用 HTTP POST 請求中提供的資料作為 JSON 主體和多個輸出繫結,將記錄新增至兩個不同資料表 (dbo.ToDodbo.RequestLog) 的資料庫的 C# 指令碼函式

第二個資料表 dbo.RequestLog,對應至下列定義:

CREATE TABLE dbo.RequestLog (
    Id int identity(1,1) primary key,
    RequestTimeStamp datetime2 not null,
    ItemCount int not null
)

以下是 function.json 檔案中的繫結資料:

{
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
        "post"
    ]
},
{
    "type": "http",
    "direction": "out",
    "name": "res"
},
{
    "name": "todoItem",
    "type": "sql",
    "direction": "out",
    "commandText": "dbo.ToDo",
    "connectionStringSetting": "SqlConnectionString"
},
{
    "name": "requestLog",
    "type": "sql",
    "direction": "out",
    "commandText": "dbo.RequestLog",
    "connectionStringSetting": "SqlConnectionString"
}

以下是 C# 指令碼程式碼範例:

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static IActionResult Run(HttpRequest req, ILogger log, out ToDoItem todoItem, out RequestLog requestLog)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string requestBody = new StreamReader(req.Body).ReadToEnd();
    todoItem = JsonConvert.DeserializeObject<ToDoItem>(requestBody);

    requestLog = new RequestLog();
    requestLog.RequestTimeStamp = DateTime.Now;
    requestLog.ItemCount = 1;

    return new OkObjectResult(todoItem);
}

public class RequestLog {
    public DateTime RequestTimeStamp { get; set; }
    public int ItemCount { get; set; }
}

RabbitMQ 輸出

下列範例說明 function.json 檔案中的 RabbitMQ 輸出繫結,以及使用此繫結的 C# 指令碼函式。 函式會從 HTTP 觸發程序讀取訊息,並將其輸出至 RabbitMQ 佇列。

以下是 function.json 檔案中的繫結資料:

{
    "bindings": [
        {
            "type": "httpTrigger",
            "direction": "in",
            "authLevel": "function",
            "name": "input",
            "methods": [
                "get",
                "post"
            ]
        },
        {
            "type": "rabbitMQ",
            "name": "outputMessage",
            "queueName": "outputQueue",
            "connectionStringSetting": "rabbitMQConnectionAppSetting",
            "direction": "out"
        }
    ]
}

以下是 C# 指令碼程式碼:

using System;
using Microsoft.Extensions.Logging;

public static void Run(string input, out string outputMessage, ILogger log)
{
    log.LogInformation(input);
    outputMessage = input;
}

SendGrid 輸出

下列範例說明 function.json 檔案中的 SendGrid 輸出繫結,以及使用此繫結的 C# 指令碼函式

以下是 function.json 檔案中的繫結資料:

{
    "bindings": [
        {
          "type": "queueTrigger",
          "name": "mymsg",
          "queueName": "myqueue",
          "connection": "AzureWebJobsStorage",
          "direction": "in"
        },
        {
          "type": "sendGrid",
          "name": "$return",
          "direction": "out",
          "apiKey": "SendGridAPIKeyAsAppSetting",
          "from": "{FromEmail}",
          "to": "{ToEmail}"
        }
    ]
}

以下是 C# 指令碼程式碼:

#r "SendGrid"

using System;
using SendGrid.Helpers.Mail;
using Microsoft.Azure.WebJobs.Host;

public static SendGridMessage Run(Message mymsg, ILogger log)
{
    SendGridMessage message = new SendGridMessage()
    {
        Subject = $"{mymsg.Subject}"
    };
    
    message.AddContent("text/plain", $"{mymsg.Content}");

    return message;
}
public class Message
{
    public string ToEmail { get; set; }
    public string FromEmail { get; set; }
    public string Subject { get; set; }
    public string Content { get; set; }
}

SignalR 觸發程序

以下是 function.json 檔案中的範例繫結資料:

{
    "type": "signalRTrigger",
    "name": "invocation",
    "hubName": "SignalRTest",
    "category": "messages",
    "event": "SendMessage",
    "parameterNames": [
        "message"
    ],
    "direction": "in"
}

而且,是程式碼如下:

#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using System;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
using Microsoft.Extensions.Logging;

public static void Run(InvocationContext invocation, string message, ILogger logger)
{
    logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
}

SignalR 輸入

下列範例示範 function.json 檔案中的 SignalR 連線資訊輸入繫結,以及使用繫結來傳回連線資訊的 C# 指令碼函數

以下是 function.json 檔案中的繫結資料:

function.json 範例:

{
    "type": "signalRConnectionInfo",
    "name": "connectionInfo",
    "hubName": "chat",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "direction": "in"
}

以下是 C# 指令碼程式碼:

#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

public static SignalRConnectionInfo Run(HttpRequest req, SignalRConnectionInfo connectionInfo)
{
    return connectionInfo;
}

您可以使用繫結運算式{headers.x-ms-client-principal-id}{headers.x-ms-client-principal-name},將繫結的 userId 屬性設為任一標頭的值。

function.json 範例:

{
    "type": "signalRConnectionInfo",
    "name": "connectionInfo",
    "hubName": "chat",
    "userId": "{headers.x-ms-client-principal-id}",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "direction": "in"
}

以下是 C# 指令碼程式碼:

#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

public static SignalRConnectionInfo Run(HttpRequest req, SignalRConnectionInfo connectionInfo)
{
    // connectionInfo contains an access key token with a name identifier
    // claim set to the authenticated user
    return connectionInfo;
}

SignalR 輸出

以下是 function.json 檔案中的繫結資料:

function.json 範例:

{
  "type": "signalR",
  "name": "signalRMessages",
  "hubName": "<hub_name>",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}

以下是 C# 指令碼程式碼:

#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

public static Task Run(
    object message,
    IAsyncCollector<SignalRMessage> signalRMessages)
{
    return signalRMessages.AddAsync(
        new SignalRMessage
        {
            Target = "newMessage",
            Arguments = new [] { message }
        });
}

您可以藉由設定 SignalR Service 訊息的使用者識別碼,僅將訊息傳送給已對使用者驗證的連線。

function.json 範例:

{
  "type": "signalR",
  "name": "signalRMessages",
  "hubName": "<hub_name>",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}

以下是 C# 指令碼程式碼:

#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

public static Task Run(
    object message,
    IAsyncCollector<SignalRMessage> signalRMessages)
{
    return signalRMessages.AddAsync(
        new SignalRMessage
        {
            // the message will only be sent to this user ID
            UserId = "userId1",
            Target = "newMessage",
            Arguments = new [] { message }
        });
}

您可以藉由設定 SignalR Service 訊息的群組名稱,僅將訊息傳送給已新增至群組的連線。

function.json 範例:

{
  "type": "signalR",
  "name": "signalRMessages",
  "hubName": "<hub_name>",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}

以下是 C# 指令碼程式碼:

#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

public static Task Run(
    object message,
    IAsyncCollector<SignalRMessage> signalRMessages)
{
    return signalRMessages.AddAsync(
        new SignalRMessage
        {
            // the message will be sent to the group with this name
            GroupName = "myGroup",
            Target = "newMessage",
            Arguments = new [] { message }
        });
}

SignalR Service 允許使用者或連線新增至群組。 訊息可以接著傳送至群組。 您可以使用 SignalR 輸出繫結來管理群組。

下列範例會將使用者新增至群組。

function.json 範例

{
    "type": "signalR",
    "name": "signalRGroupActions",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "hubName": "chat",
    "direction": "out"
}

Run.csx

#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

public static Task Run(
    HttpRequest req,
    ClaimsPrincipal claimsPrincipal,
    IAsyncCollector<SignalRGroupAction> signalRGroupActions)
{
    var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);
    return signalRGroupActions.AddAsync(
        new SignalRGroupAction
        {
            UserId = userIdClaim.Value,
            GroupName = "myGroup",
            Action = GroupAction.Add
        });
}

下列範例會從群組中移除使用者。

function.json 範例

{
    "type": "signalR",
    "name": "signalRGroupActions",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "hubName": "chat",
    "direction": "out"
}

Run.csx

#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

public static Task Run(
    HttpRequest req,
    ClaimsPrincipal claimsPrincipal,
    IAsyncCollector<SignalRGroupAction> signalRGroupActions)
{
    var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);
    return signalRGroupActions.AddAsync(
        new SignalRGroupAction
        {
            UserId = userIdClaim.Value,
            GroupName = "myGroup",
            Action = GroupAction.Remove
        });
}

Twilio 輸出

下列範例說明 function.json 檔案中的 Twilio 輸出繫結,以及使用此繫結的 C# 指令碼函式。 此函式會使用 out 參數來傳送文字簡訊。

以下是 function.json 檔案中的繫結資料:

function.json 範例:

{
  "type": "twilioSms",
  "name": "message",
  "accountSidSetting": "TwilioAccountSid",
  "authTokenSetting": "TwilioAuthToken",
  "from": "+1425XXXXXXX",
  "direction": "out",
  "body": "Azure Functions Testing"
}

以下是 C# 指令碼:

#r "Newtonsoft.Json"
#r "Twilio"
#r "Microsoft.Azure.WebJobs.Extensions.Twilio"

using System;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;

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

    // In this example the queue item is a JSON string representing an order that contains the name of a
    // customer and a mobile number to send text updates to.
    dynamic order = JsonConvert.DeserializeObject(myQueueItem);
    string msg = "Hello " + order.name + ", thank you for your order.";

    // You must initialize the CreateMessageOptions variable with the "To" phone number.
    message = new CreateMessageOptions(new PhoneNumber("+1704XXXXXXX"));

    // A dynamic message can be set instead of the body in the output binding. In this example, we use
    // the order information to personalize a text message.
    message.Body = msg;
}

您無法使用非同步程式碼中的 out 參數。 以下是非同步的 C# 指令碼範例:

#r "Newtonsoft.Json"
#r "Twilio"
#r "Microsoft.Azure.WebJobs.Extensions.Twilio"

using System;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;

public static async Task Run(string myQueueItem, IAsyncCollector<CreateMessageOptions> message,  ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");

    // In this example the queue item is a JSON string representing an order that contains the name of a
    // customer and a mobile number to send text updates to.
    dynamic order = JsonConvert.DeserializeObject(myQueueItem);
    string msg = "Hello " + order.name + ", thank you for your order.";

    // You must initialize the CreateMessageOptions variable with the "To" phone number.
    CreateMessageOptions smsText = new CreateMessageOptions(new PhoneNumber("+1704XXXXXXX"));

    // A dynamic message can be set instead of the body in the output binding. In this example, we use
    // the order information to personalize a text message.
    smsText.Body = msg;

    await message.AddAsync(smsText);
}

準備觸發程序

下列範例顯示 function.json 檔案中的準備觸發程序,以及將各執行個體新增至應用程式時所執行的 C# 指令碼函數

1.x 版的 Functions 執行階段不支援。

以下是 function.json 檔案:

{
    "bindings": [
        {
            "type": "warmupTrigger",
            "direction": "in",
            "name": "warmupContext"
        }
    ]
}
public static void Run(WarmupContext warmupContext, ILogger log)
{
    log.LogInformation("Function App instance is warm.");  
}

下一步