Azure Functions 绑定表达式模式

触发器和绑定的最强大功能之一是绑定表达式。 在 function.json 文件、函数参数和代码中,可以使用表达式解析为各种源的值。

大多数表达式的标识方式是将其包装在大括号中。 例如,在队列触发器函数中,{queueTrigger} 解析为队列消息文本。 如果 Blob 输出绑定的 path 属性为 container/{queueTrigger},并且函数由队列消息 HelloWorld 触发,则创建名为 HelloWorld 的 Blob。

绑定表达式的类型

绑定表达式 - 应用设置

作为最佳做法,应使用应用设置(而不是配置文件)来管理密钥和连接字符串。 这会限制对这些密钥的访问,并可在公共源代码管理存储库中安全存储 function.json 等文件。

应用设置在想要根据环境更改配置时也很有用。 例如,在测试环境中,可能想要监视不同的队列或 blob 存储容器。

应用设置绑定表达式的标识方式不同于其他绑定表达式:它们包装在百分比号而不是大括号中。 例如,如果 Blob 输出绑定路径为 %Environment%/newblob.txtEnvironment 应用设置值为 Development,则会在 Development 容器中创建 Blob。

当函数在本地运行时,应用设置值来自 local.settings.json 文件。

注意

触发器和绑定的 connection 属性是一种特殊情况,该属性会自动将值解析为应用设置(不带百分比号)。

以下示例是一个 Azure 队列存储触发器,该触发器使用应用设置 %input_queue_name% 定义要触发的队列。

{
  "bindings": [
    {
      "name": "order",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "%input_queue_name%",
      "connection": "MY_STORAGE_ACCT_APP_SETTING"
    }
  ]
}

可在类库中使用此相同的方法:

[FunctionName("QueueTrigger")]
public static void Run(
    [QueueTrigger("%input_queue_name%")]string myQueueItem, 
    ILogger log)
{
    log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
}

触发器文件名

Blob 触发器的 path 可以是一种模式,用于引用其他绑定和函数代码中的触发 Blob 的名称。 该模式还可包含筛选条件,用于指定哪些 Blob 可以触发函数调用。

例如,在以下 Blob 触发器绑定中,path 模式为 sample-images/{filename}(创建名为 filename 的绑定表达式):

{
  "bindings": [
    {
      "name": "image",
      "type": "blobTrigger",
      "path": "sample-images/{filename}",
      "direction": "in",
      "connection": "MyStorageConnection"
    },
    ...

然后,可以在输出绑定中使用表达式 filename,用于指定所创建的 Blob 的名称:

    ...
    {
      "name": "imageSmall",
      "type": "blob",
      "path": "sample-images-sm/{filename}",
      "direction": "out",
      "connection": "MyStorageConnection"
    }
  ],
}

函数代码可以使用 filename 作为参数名称来访问相同的值:

// C# example of binding to {filename}
public static void Run(Stream image, string filename, Stream imageSmall, ILogger log)  
{
    log.LogInformation($"Blob trigger processing: {filename}");
    // ...
} 

类库中的特性同样能够使用绑定表达式和模式。 在以下示例中,特性构造函数参数的值与前面 function.json 示例中的 path 值相同:

[FunctionName("ResizeImage")]
public static void Run(
    [BlobTrigger("sample-images/{filename}")] Stream image,
    [Blob("sample-images-sm/{filename}", FileAccess.Write)] Stream imageSmall,
    string filename,
    ILogger log)
{
    log.LogInformation($"Blob trigger processing: {filename}");
    // ...
}

还可针对文件名的某些部分创建表达式。 在下面的示例中,仅对匹配以下模式的文件名触发函数:anyname-anyfile.csv

{
    "name": "myBlob",
    "type": "blobTrigger",
    "direction": "in",
    "path": "testContainerName/{date}-{filetype}.csv",
    "connection": "OrderStorageConnection"
}

有关如何在 Blob 路径字符串中使用表达式和模式的详细信息,请参阅存储 Blob 绑定参考

触发器元数据

除了触发器提供的数据有效负载(如触发函数的队列消息内容),许多触发器还会提供其他元数据值。 这些值可用作 C# 和 F# 中的输入参数,或用作 JavaScript 中 context.bindings 对象的属性。

例如,Azure 队列存储触发器支持以下属性:

  • QueueTrigger - 如果字符串有效,将触发消息内容
  • DequeueCount
  • ExpirationTime
  • ID
  • InsertionTime
  • NextVisibleTime
  • PopReceipt

这些元数据值可在 function.json 文件属性中访问。 例如,假设使用队列触发器,且队列消息中包含要读取的 blob 的名称。 在 function.json 文件中,可在 blob path 属性中使用 queueTrigger 元数据属性,如下面的示例中所示:

{
  "bindings": [
    {
      "name": "myQueueItem",
      "type": "queueTrigger",
      "queueName": "myqueue-items",
      "connection": "MyStorageConnection",
    },
    {
      "name": "myInputBlob",
      "type": "blob",
      "path": "samples-workitems/{queueTrigger}",
      "direction": "in",
      "connection": "MyStorageConnection"
    }
  ]
}

相应参考文章中会详细介绍每种触发器的元数据属性。 有关示例,请参阅队列触发器元数据。 在门户“集成”选项卡的绑定配置区域下方的“文档”部分中,还提供了文档。

JSON 有效负载

在某些情况下,可以参考相同函数和函数代码中的其他绑定的配置中的触发器有效负载属性。 这要求触发器有效负载为 JSON,并且小于每个触发器的特定阈值。 通常,有效负载大小需要小于 100MB,但你应检查每个触发器的引用内容。 使用触发器有效负载属性可能会影响应用程序的性能,它会强制触发器参数类型为简单类型,如字符串或表示 JSON 数据的自定义对象类型。 它不能与流、客户端或其他 SDK 类型一起使用。

以下示例演示一个接收 JSON 格式 Blob 名称的 Webhook 函数的 function.json 文件:{"BlobName":"HelloWorld.txt"}。 Blob 输入绑定读取 Blob,HTTP 输出绑定在 HTTP 响应中返回 Blob 内容。 可以看到,Blob 输入绑定通过直接引用 BlobName 属性来获取 Blob 名称 ("path": "strings/{BlobName}")

{
  "bindings": [
    {
      "name": "info",
      "type": "httpTrigger",
      "direction": "in",
      "webHookType": "genericJson"
    },
    {
      "name": "blobContents",
      "type": "blob",
      "direction": "in",
      "path": "strings/{BlobName}",
      "connection": "AzureWebJobsStorage"
    },
    {
      "name": "res",
      "type": "http",
      "direction": "out"
    }
  ]
}

要在 C# 和 F# 中运行此代码,需要使用一个类来定义要反序列化的字段,如以下示例中所示:

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

public class BlobInfo
{
    public string BlobName { get; set; }
}
  
public static HttpResponseMessage Run(HttpRequestMessage req, BlobInfo info, string blobContents, ILogger log)
{
    if (blobContents == null) {
        return req.CreateResponse(HttpStatusCode.NotFound);
    } 

    log.LogInformation($"Processing: {info.BlobName}");

    return req.CreateResponse(HttpStatusCode.OK, new {
        data = $"{blobContents}"
    });
}

在 JavaScript 中,会自动执行 JSON 反序列化。

module.exports = async function (context, info) {
    if ('BlobName' in info) {
        context.res = {
            body: { 'data': context.bindings.blobContents }
        }
    }
    else {
        context.res = {
            status: 404
        };
    }
}

点表示法

如果 JSON 有效负载中的某些属性是包含属性的对象,可以使用点 (.) 表示法直接引用这些对象。 此表示法不适用于 Azure Cosmos DB表存储绑定。

例如,假设 JSON 如下所示:

{
  "BlobName": {
    "FileName":"HelloWorld",
    "Extension":"txt"
  }
}

可以直接以 BlobName.FileName 的形式引用 FileName。 使用此 JSON 格式时,上述示例中的 path 属性如下所示:

"path": "strings/{BlobName.FileName}.{BlobName.Extension}",

在 C# 中,需要两个类:

public class BlobInfo
{
    public BlobName BlobName { get; set; }
}
public class BlobName
{
    public string FileName { get; set; }
    public string Extension { get; set; }
}

创建 GUID

{rand-guid} 绑定表达式用于创建 GUID。 function.json 文件中的以下 Blob 路径创建名称类似于 50710cb5-84b9-4d87-9d83-a03d6976a682.txt 的 Blob。

{
  "type": "blob",
  "name": "blobOutput",
  "direction": "out",
  "path": "my-output-container/{rand-guid}.txt"
}

当前时间

绑定表达式 DateTime 解析为 DateTime.UtcNowfunction.json 文件中的以下 Blob 路径创建名称类似于 2018-02-16T17-59-55Z.txt 的 Blob。

{
  "type": "blob",
  "name": "blobOutput",
  "direction": "out",
  "path": "my-output-container/{DateTime}.txt"
}

在运行时绑定

在 C# 和其他 .NET 语言中,可以使用命令性绑定模式,而不是 function.json 和特性中的声明式绑定。 当绑定参数需要在运行时(而非在设计时)计算时,命令性绑定很有用。 若要了解详细信息,请参阅 C# 开发人员参考C# 脚本开发人员参考