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

还可为文件名的某些部分(例如扩展)创建表达式。 有关如何在 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 时,可以在相同的函数和函数代码中,引用其他绑定的配置中的相应属性。

以下示例演示一个接收 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 = function (context, info) {
    if ('BlobName' in info) {
        context.res = {
            body: { 'data': context.bindings.blobContents }
        }
    }
    else {
        context.res = {
            status: 404
        };
    }
    context.done();
}

点表示法

如果 JSON 有效负载中的某些属性是包含属性的对象,可以使用点表示法直接引用这些对象。 例如,假设 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}"
}

当前时间

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

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

在运行时绑定

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

后续步骤