您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

Azure Functions 的事件网格触发器Event Grid trigger for Azure Functions

本文介绍如何处理 Azure Functions 中的事件网格事件。This article explains how to handle Event Grid events in Azure Functions.

事件网格是一个 Azure 服务,它可以发送 HTTP 请求来告知发布方中发生的事件情况。 Event Grid is an Azure service that sends HTTP requests to notify you about events that happen in publishers. 发布方是发起事件的服务或资源。A publisher is the service or resource that originates the event. 例如,Azure Blob 存储帐户是发布方,而 Blob 上传或删除是事件For example, an Azure blob storage account is a publisher, and a blob upload or deletion is an event. 某些 Azure 服务原生支持向事件网格发布事件Some Azure services have built-in support for publishing events to Event Grid.

事件处理程序接收并处理事件。 Event handlers receive and process events. Azure Functions 是原生支持处理事件网格事件的多个 Azure 服务之一。Azure Functions is one of several Azure services that have built-in support for handling Event Grid events. 本文将会介绍在收到事件网格发出的事件时,如何使用事件网格触发器调用某个函数。In this article, you learn how to use an Event Grid trigger to invoke a function when an event is received from Event Grid.

如果需要,可以使用 HTTP 触发器来处理事件网格事件;请参阅本文稍后介绍的将 HTTP 触发器用作事件网格触发器If you prefer, you can use an HTTP trigger to handle Event Grid Events; see Use an HTTP trigger as an Event Grid trigger later in this article. 目前,在以 CloudEvents 架构传递事件时,无法为 Azure Functions 应用使用事件网格触发器。Currently, you can't use an Event Grid trigger for an Azure Functions app when the event is delivered in the CloudEvents schema. 应转而使用 HTTP 触发器。Instead, use an HTTP trigger.

此参考信息面向 Azure Functions 开发人员。This is reference information for Azure Functions developers. Azure Functions 的新手请从以下资源入手:If you're new to Azure Functions, start with the following resources:

包 - Functions 2.xPackages - Functions 2.x

Microsoft.Azure.WebJobs.Extensions.EventGrid NuGet 包 2.x 版中提供了事件网格触发器。The Event Grid trigger is provided in the Microsoft.Azure.WebJobs.Extensions.EventGrid NuGet package, version 2.x. azure-functions-eventgrid-extension GitHub 存储库中提供了此包的源代码。Source code for the package is in the azure-functions-eventgrid-extension GitHub repository.

下表说明了如何在每个开发环境中添加对此绑定的支持。The following table tells how to add support for this binding in each development environment.

开发环境Development environment 添加支持To add support in
Functions 2.xFunctions 2.x
本地开发 - C# 类库Local development - C# class library 安装包Install the package
本地开发 - C# 脚本、JavaScript、F#、Java 和 PythonLocal development - C# script, JavaScript, F#, Java and Python 注册扩展Register the extension
门户开发Portal development 添加输出绑定时安装Install when adding output binding

若要了解如何更新门户中的现有绑定扩展而不必重新发布函数应用项目,请参阅更新扩展To learn how to update existing binding extensions in the portal without having to republish your function app project, see Update your extensions.

包 - Functions 1.xPackages - Functions 1.x

Microsoft.Azure.WebJobs.Extensions.EventGrid NuGet 包 1.x 版中提供了事件网格触发器。The Event Grid trigger is provided in the Microsoft.Azure.WebJobs.Extensions.EventGrid NuGet package, version 1.x. azure-functions-eventgrid-extension GitHub 存储库中提供了此包的源代码。Source code for the package is in the azure-functions-eventgrid-extension GitHub repository.

下表说明了如何在每个开发环境中添加对此绑定的支持。The following table tells how to add support for this binding in each development environment.

开发环境Development environment 添加支持To add support in
Functions 1.xFunctions 1.x
本地开发 - C# 类库Local development - C# class library 安装包Install the package
本地开发 - C# 脚本、JavaScript、F#Local development - C# script, JavaScript, F# 自动Automatic
门户开发Portal development 自动Automatic

示例Example

请参阅有关事件网格触发器的特定于语言的示例:See the language-specific example for an Event Grid trigger:

有关 HTTP 触发器示例,请参阅本文稍后介绍的如何使用 HTTP 触发器For an HTTP trigger example, see How to use HTTP trigger later in this article.

C# (2.x)C# (2.x)

以下示例演示绑定到 EventGridEvent 的 Functions 2.x C# 函数The following example shows a Functions 2.x C# function that binds to EventGridEvent:

using Microsoft.Azure.EventGrid.Models;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.EventGrid;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;

namespace Company.Function
{
    public static class EventGridTriggerCSharp
    {
        [FunctionName("EventGridTest")]
        public static void EventGridTest([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log)
        {
            log.LogInformation(eventGridEvent.Data.ToString());
        }
    }
}

有关详细信息,请参阅包、特性配置用法For more information, see Packages, Attributes, Configuration, and Usage.

C#(版本 1.x)C# (Version 1.x)

以下示例演示绑定到 JObject 的 Functions 1.x C# 函数The following example shows a Functions 1.x C# function that binds to JObject:

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

namespace Company.Function
{
    public static class EventGridTriggerCSharp
    {
        [FunctionName("EventGridTriggerCSharp")]
        public static void Run([EventGridTrigger]JObject eventGridEvent, ILogger log)
        {
            log.LogInformation(eventGridEvent.ToString(Formatting.Indented));
        }
    }
}

C# 脚本示例C# script example

以下示例演示 function.json 文件中的一个触发器绑定以及使用该绑定的 C# 脚本函数The following example shows a trigger binding in a function.json file and a C# script function that uses the binding.

下面是 function.json 文件中的绑定数据:Here's the binding data in the function.json file:

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

C# 脚本(版本 2.x)C# script (Version 2.x)

下面是绑定到 EventGridEvent 的 Functions 2.x C# 脚本代码:Here's Functions 2.x C# script code that binds to EventGridEvent:

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

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

有关详细信息,请参阅包、特性配置用法For more information, see Packages, Attributes, Configuration, and Usage.

C# 脚本(版本 1.x)C# script (Version 1.x)

下面是绑定到 JObject 的 Functions 1.x C# 脚本代码:Here's Functions 1.x C# script code that binds to JObject:

#r "Newtonsoft.Json"

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

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

JavaScript 示例JavaScript example

以下示例演示 function.json 文件中的一个触发器绑定以及使用该绑定的 JavaScript 函数The following example shows a trigger binding in a function.json file and a JavaScript function that uses the binding.

下面是 function.json 文件中的绑定数据:Here's the binding data in the function.json file:

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

JavaScript 代码如下所示:Here's the JavaScript code:

module.exports = function (context, eventGridEvent) {
    context.log("JavaScript Event Grid function processed a request.");
    context.log("Subject: " + eventGridEvent.subject);
    context.log("Time: " + eventGridEvent.eventTime);
    context.log("Data: " + JSON.stringify(eventGridEvent.data));
    context.done();
};

Python 示例Python example

以下示例演示 function.json 文件中的一个触发器绑定以及使用该绑定的 Python 函数The following example shows a trigger binding in a function.json file and a Python function that uses the binding.

下面是 function.json 文件中的绑定数据:Here's the binding data in the function.json file:

{
  "bindings": [
    {
      "type": "eventGridTrigger",
      "name": "event",
      "direction": "in"
    }
  ],
  "disabled": false,
  "scriptFile": "__init__.py"
}

下面是 Python 代码:Here's the Python code:

import logging
import azure.functions as func


def main(event: func.EventGridEvent):
    logging.info("Python Event Grid function processed a request.")
    logging.info("  Subject: %s", event.subject)
    logging.info("  Time: %s", event.event_time)
    logging.info("  Data: %s", event.get_json())

触发器 - Java 示例Trigger - Java examples

本部分包含以下示例:This section contains the following examples:

以下示例显示了 function.json 文件和 Java 函数中的触发器绑定,这些函数使用绑定并打印出事件,首先接收 String 形式的事件,第二个接收 POJO 形式的事件。The following examples show trigger binding in a function.json file and Java functions that use the binding and print out an event, first receiving the event as String and second as a POJO.

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

事件网格触发器、字符串参数 (Java)Event Grid trigger, String parameter (Java)

  @FunctionName("eventGridMonitorString")
  public void logEvent(
    @EventGridTrigger(
      name = "event"
    ) 
    String content, 
    final ExecutionContext context) {
      // log 
      context.getLogger().info("Event content: " + content);      
  }

事件网格触发器、POJO 参数 (Java)Event Grid trigger, POJO parameter (Java)

此示例使用以下 POJO 表示事件网格事件的顶级属性:This example uses the following POJO, representing the top-level properties of an Event Grid event:

import java.util.Date;
import java.util.Map;

public class EventSchema {

  public String topic;
  public String subject;
  public String eventType;
  public Date eventTime;
  public String id;
  public String dataVersion;
  public String metadataVersion;
  public Map<String, Object> data;

}

到达后,事件的 JSON 有效负载被反序列化为 EventSchema POJO 以供函数使用。Upon arrival, the event's JSON payload is de-serialized into the EventSchema POJO for use by the function. 这样,函数便能以面向对象的方式访问事件的属性。This allows the function to access the event's properties in an object-oriented way.

  @FunctionName("eventGridMonitor")
  public void logEvent(
    @EventGridTrigger(
      name = "event"
    ) 
    EventSchema event, 
    final ExecutionContext context) {
      // log 
      context.getLogger().info("Event content: ");
      context.getLogger().info("Subject: " + event.subject);
      context.getLogger().info("Time: " + event.eventTime); // automatically converted to Date by the runtime
      context.getLogger().info("Id: " + event.id);
      context.getLogger().info("Data: " + event.data);
  }

Java 函数运行时库中,对其值将来自 EventGrid 的参数使用 EventGridTrigger 注释。In the Java functions runtime library, use the EventGridTrigger annotation on parameters whose value would come from EventGrid. 带有这些注释的参数会导致函数在事件到达时运行。Parameters with these annotations cause the function to run when an event arrives. 可以将此注释与本机 Java 类型、POJO 或使用了 Optional<T> 的可为 null 的值一起使用。This annotation can be used with native Java types, POJOs, or nullable values using Optional<T>.

属性Attributes

C# 类库中,使用 EventGridTrigger 特性。In C# class libraries, use the EventGridTrigger attribute.

下面是某个方法签名中的 EventGridTrigger 特性:Here's an EventGridTrigger attribute in a method signature:

[FunctionName("EventGridTest")]
public static void EventGridTest([EventGridTrigger] JObject eventGridEvent, ILogger log)
{
    ...
}

有关完整示例,请参阅 C# 示例。For a complete example, see C# example.

配置Configuration

下表解释了在 function.json 文件中设置的绑定配置属性。The following table explains the binding configuration properties that you set in the function.json file. 无法在 EventGridTrigger 特性中设置任何构造函数参数或属性。There are no constructor parameters or properties to set in the EventGridTrigger attribute.

function.json 属性function.json property 描述Description
type type 必需 - 必须设置为 eventGridTriggerRequired - must be set to eventGridTrigger.
direction direction 必需 - 必须设置为 inRequired - must be set to in.
name name 必需 - 在函数代码中对接收事件数据的参数使用的变量名称。Required - the variable name used in function code for the parameter that receives the event data.

使用情况Usage

在 Azure Functions 1.x 的 C# 和 F# 函数中,可以为事件网格触发器使用以下参数类型:For C# and F# functions in Azure Functions 1.x, you can use the following parameter types for the Event Grid trigger:

  • JObject
  • string

在 Azure Functions 2.x 的 C# 和 F# 函数中,还可以选择为事件网格触发器使用以下参数类型:For C# and F# functions in Azure Functions 2.x, you also have the option to use the following parameter type for the Event Grid trigger:

  • Microsoft.Azure.EventGrid.Models.EventGridEvent - 定义所有事件类型通用的字段的属性。Microsoft.Azure.EventGrid.Models.EventGridEvent- Defines properties for the fields common to all event types.

备注

在 Functions v1 中,如果尝试绑定到 Microsoft.Azure.WebJobs.Extensions.EventGrid.EventGridEvent,编译器将显示“已弃用”消息,并建议你改用 Microsoft.Azure.EventGrid.Models.EventGridEventIn Functions v1 if you try to bind to Microsoft.Azure.WebJobs.Extensions.EventGrid.EventGridEvent, the compiler will display a "deprecated" message and advise you to use Microsoft.Azure.EventGrid.Models.EventGridEvent instead. 若要使用较新类型,请引用 Microsoft.Azure.EventGrid NuGet 包,并通过为 EventGridEvent 类型名称添加 Microsoft.Azure.EventGrid.Models 前缀来对其进行完全限定。To use the newer type, reference the Microsoft.Azure.EventGrid NuGet package and fully qualify the EventGridEvent type name by prefixing it with Microsoft.Azure.EventGrid.Models. 有关如何在 C# 脚本函数中引用 NuGet 包的信息,请参阅使用 NuGet 包For information about how to reference NuGet packages in a C# script function, see Using NuGet packages

对于 JavaScript 函数,由 function.json name 属性命名的参数包含对事件对象的引用。For JavaScript functions, the parameter named by the function.json name property has a reference to the event object.

事件架构Event schema

事件网格事件的数据在 HTTP 请求的正文中以 JSON 对象形式接收。Data for an Event Grid event is received as a JSON object in the body of an HTTP request. 该 JSON 如以下示例所示:The JSON looks similar to the following example:

[{
  "topic": "/subscriptions/{subscriptionid}/resourceGroups/eg0122/providers/Microsoft.Storage/storageAccounts/egblobstore",
  "subject": "/blobServices/default/containers/{containername}/blobs/blobname.jpg",
  "eventType": "Microsoft.Storage.BlobCreated",
  "eventTime": "2018-01-23T17:02:19.6069787Z",
  "id": "{guid}",
  "data": {
    "api": "PutBlockList",
    "clientRequestId": "{guid}",
    "requestId": "{guid}",
    "eTag": "0x8D562831044DDD0",
    "contentType": "application/octet-stream",
    "contentLength": 2248,
    "blobType": "BlockBlob",
    "url": "https://egblobstore.blob.core.windows.net/{containername}/blobname.jpg",
    "sequencer": "000000000000272D000000000003D60F",
    "storageDiagnostics": {
      "batchId": "{guid}"
    }
  },
  "dataVersion": "",
  "metadataVersion": "1"
}]

显示的示例是包含一个元素的数组。The example shown is an array of one element. 事件网格始终发送一个数组,并可能在该数组中发送多个事件。Event Grid always sends an array and may send more than one event in the array. 运行时针对每个数组元素调用你的函数一次。The runtime invokes your function once for each array element.

事件 JSON 数据中的顶级属性在所有事件类型中相同,而 data 属性的内容特定于每个事件类型。The top-level properties in the event JSON data are the same among all event types, while the contents of the data property are specific to each event type. 显示的示例适用于 Blob 存储事件。The example shown is for a blob storage event.

有关通用和特定于事件的属性的说明,请参阅事件网格文档中的事件属性For explanations of the common and event-specific properties, see Event properties in the Event Grid documentation.

EventGridEvent 类型只定义顶级属性;Data 属性是 JObjectThe EventGridEvent type defines only the top-level properties; the Data property is a JObject.

创建订阅Create a subscription

若要开始接收事件网格 HTTP 请求,请创建一个事件网格订阅,用于指定可调用函数的终结点 URL。To start receiving Event Grid HTTP requests, create an Event Grid subscription that specifies the endpoint URL that invokes the function.

Azure 门户Azure portal

对于在 Azure 门户中使用事件网格触发器开发的函数,请选择“添加事件网格订阅”。 For functions that you develop in the Azure portal with the Event Grid trigger, select Add Event Grid subscription.

在门户中创建订阅

选择此链接时,门户将打开“创建事件订阅”页,其中预先填充了终结点 URL。 When you select this link, the portal opens the Create Event Subscription page with the endpoint URL prefilled.

预先填充的终结点 URL

有关如何使用 Azure 门户创建订阅的详细信息,请参阅事件网格文档中的创建自定义事件 - Azure 门户For more information about how to create subscriptions by using the Azure portal, see Create custom event - Azure portal in the Event Grid documentation.

Azure CLIAzure CLI

若要使用 Azure CLI 创建订阅,请运行 az eventgrid event-subscription create 命令。To create a subscription by using the Azure CLI, use the az eventgrid event-subscription create command.

该命令需要可调用函数的终结点 URL。The command requires the endpoint URL that invokes the function. 以下示例显示特定于版本的 URL 模式:The following example shows the version-specific URL pattern:

2.x 版运行时Version 2.x runtime

https://{functionappname}.azurewebsites.net/runtime/webhooks/eventgrid?functionName={functionname}&code={systemkey}

1.x 版运行时Version 1.x runtime

https://{functionappname}.azurewebsites.net/admin/extensions/EventGridExtensionConfig?functionName={functionname}&code={systemkey}

系统密钥是必须包含在事件网格触发器终结点 URL 中的授权密钥。The system key is an authorization key that has to be included in the endpoint URL for an Event Grid trigger. 以下部分介绍如何获取系统密钥。The following section explains how to get the system key.

下面是一个订阅 Blob 存储帐户的示例(包含系统密钥的占位符):Here's an example that subscribes to a blob storage account (with a placeholder for the system key):

2.x 版运行时Version 2.x runtime

az eventgrid resource event-subscription create -g myResourceGroup \
--provider-namespace Microsoft.Storage --resource-type storageAccounts \
--resource-name myblobstorage12345 --name myFuncSub  \
--included-event-types Microsoft.Storage.BlobCreated \
--subject-begins-with /blobServices/default/containers/images/blobs/ \
--endpoint https://mystoragetriggeredfunction.azurewebsites.net/runtime/webhooks/eventgrid?functionName=imageresizefunc&code=<key>

1.x 版运行时Version 1.x runtime

az eventgrid resource event-subscription create -g myResourceGroup \
--provider-namespace Microsoft.Storage --resource-type storageAccounts \
--resource-name myblobstorage12345 --name myFuncSub  \
--included-event-types Microsoft.Storage.BlobCreated \
--subject-begins-with /blobServices/default/containers/images/blobs/ \
--endpoint https://mystoragetriggeredfunction.azurewebsites.net/admin/extensions/EventGridExtensionConfig?functionName=imageresizefunc&code=<key>

有关如何创建订阅的详细信息,请参阅 Blob 存储快速入门或其他事件网格快速入门。For more information about how to create a subscription, see the blob storage quickstart or the other Event Grid quickstarts.

获取系统密钥Get the system key

可以使用以下 API (HTTP GET) 获取系统密钥:You can get the system key by using the following API (HTTP GET):

2.x 版运行时Version 2.x runtime

http://{functionappname}.azurewebsites.net/admin/host/systemkeys/eventgrid_extension?code={masterkey}

1.x 版运行时Version 1.x runtime

http://{functionappname}.azurewebsites.net/admin/host/systemkeys/eventgridextensionconfig_extension?code={masterkey}

这是一个管理 API,因此它需要函数应用主密钥This is an admin API, so it requires your function app master key. 请不要混淆系统密钥(用于调用事件网格触发器函数)和主密钥(用于针对函数应用执行管理任务)。Don't confuse the system key (for invoking an Event Grid trigger function) with the master key (for performing administrative tasks on the function app). 订阅事件网格主题时,请务必使用系统密钥。When you subscribe to an Event Grid topic, be sure to use the system key.

下面是提供系统密钥的响应示例:Here's an example of the response that provides the system key:

{
  "name": "eventgridextensionconfig_extension",
  "value": "{the system key for the function}",
  "links": [
    {
      "rel": "self",
      "href": "{the URL for the function, without the system key}"
    }
  ]
}

可以从门户中的“函数应用设置”选项卡获取函数应用的主密钥 。You can get the master key for your function app from the Function app settings tab in the portal.

重要

主密钥提供对函数应用的管理员访问权限。The master key provides administrator access to your function app. 不要与第三方共享此密钥或将其分发到本机客户端应用程序中。Don't share this key with third parties or distribute it in native client applications.

有关详细信息,请参阅 HTTP 触发器参考文章中的授权密钥For more information, see Authorization keys in the HTTP trigger reference article.

或者,可以发送 HTTP PUT 以自行指定密钥值。Alternatively, you can send an HTTP PUT to specify the key value yourself.

使用查看器 Web 应用进行本地测试Local testing with viewer web app

若要在本地测试事件网格触发器,必须获取从云中的来源位置传送到本地计算机的事件网格 HTTP 请求。To test an Event Grid trigger locally, you have to get Event Grid HTTP requests delivered from their origin in the cloud to your local machine. 实现此目的的方法之一是在线捕获请求,然后手动将其重新发送到本地计算机:One way to do that is by capturing requests online and manually resending them on your local machine:

  1. 创建查看器 Web 应用,用于捕获事件消息。Create a viewer web app that captures event messages.
  2. 创建事件网格订阅,用于向查看器应用发送事件。Create an Event Grid subscription that sends events to the viewer app.
  3. 生成请求,并从查看器应用复制请求正文。Generate a request and copy the request body from the viewer app.
  4. 将请求手动发布到事件网格触发器函数的 localhost URL。Manually post the request to the localhost URL of your Event Grid trigger function.

完成测试后,可以更新终结点,将同一订阅用于生产。When you're done testing, you can use the same subscription for production by updating the endpoint. 使用 az eventgrid event-subscription update Azure CLI 命令。Use the az eventgrid event-subscription update Azure CLI command.

创建查看器 Web 应用Create a viewer web app

若要简化事件消息捕获,可部署用于显示事件消息的预建 Web 应用To simplify capturing event messages, you can deploy a pre-built web app that displays the event messages. 所部署的解决方案包括应用服务计划、应用服务 Web 应用和 GitHub 中的源代码。The deployed solution includes an App Service plan, an App Service web app, and source code from GitHub.

选择“部署到 Azure” 将解决方案部署到你的订阅。Select Deploy to Azure to deploy the solution to your subscription. 在 Azure 门户中,为参数提供值。In the Azure portal, provide values for the parameters.

部署可能需要几分钟才能完成。The deployment may take a few minutes to complete. 部署成功后,请查看 Web 应用以确保它正在运行。After the deployment has succeeded, view your web app to make sure it's running. 在 Web 浏览器中导航到 https://<your-site-name>.azurewebsites.netIn a web browser, navigate to: https://<your-site-name>.azurewebsites.net

查看站点,但是尚未有事件发布到它。You see the site but no events have been posted to it yet.

查看新站点

创建事件网格订阅Create an Event Grid subscription

创建要测试的类型的事件网格订阅,并将 Web 应用中的 URL 作为事件通知的终结点。Create an Event Grid subscription of the type you want to test, and give it the URL from your web app as the endpoint for event notification. Web 应用的终结点必须包括后缀 /api/updates/The endpoint for your web app must include the suffix /api/updates/. 因此,完整的 URL 是 https://<your-site-name>.azurewebsites.net/api/updatesSo, the full URL is https://<your-site-name>.azurewebsites.net/api/updates

有关如何使用 Azure 门户创建订阅的信息,请参阅事件网格文档中的创建自定义事件 - Azure 门户For information about how to create subscriptions by using the Azure portal, see Create custom event - Azure portal in the Event Grid documentation.

生成请求Generate a request

触发一个事件,以便向 Web 应用终结点生成 HTTP 流量。Trigger an event that will generate HTTP traffic to your web app endpoint. 例如,如果创建了 Blob 存储订阅,请上传或删除一个 Blob。For example, if you created a blob storage subscription, upload or delete a blob. Web 应用中显示请求后,请复制请求正文。When a request shows up in your web app, copy the request body.

首先会接收订阅验证请求,忽略任何验证请求,并复制事件请求。The subscription validation request will be received first; ignore any validation requests, and copy the event request.

从 Web 应用复制请求正文

手动发布请求Manually post the request

在本地运行事件网格函数。Run your Event Grid function locally.

使用 Postmancurl 等工具创建 HTTP POST 请求:Use a tool such as Postman or curl to create an HTTP POST request:

  • 设置 Content-Type: application/json 标头。Set a Content-Type: application/json header.
  • 设置 aeg-event-type: Notification 标头。Set an aeg-event-type: Notification header.
  • 将 RequestBin 数据粘贴到请求正文。Paste the RequestBin data into the request body.
  • 发布到事件网格触发器函数的 URL。Post to the URL of your Event Grid trigger function.
    • 有关 2.x 中,使用以下模式:For 2.x use the following pattern:

      http://localhost:7071/runtime/webhooks/eventgrid?functionName={FUNCTION_NAME}
      
    • 对于 1.x 使用:For 1.x use:

      http://localhost:7071/admin/extensions/EventGridExtensionConfig?functionName={FUNCTION_NAME}
      

functionName 参数必须是在 FunctionName 特性中指定的名称。The functionName parameter must be the name specified in the FunctionName attribute.

以下屏幕截图显示了 Postman 中的标头和请求正文:The following screenshots show the headers and request body in Postman:

Postman 中的标头

Postman 中的请求正文

事件网格触发器函数将会执行,并显示类似于以下示例的日志:The Event Grid trigger function executes and shows logs similar to the following example:

事件网格触发器函数日志示例

使用 ngrok 进行本地测试Local testing with ngrok

在本地测试事件网格触发器的另一种方法是自动化 Internet 与开发计算机之间的 HTTP 连接。Another way to test an Event Grid trigger locally is to automate the HTTP connection between the Internet and your development computer. 可以执行的操作与之类的工具ngrok:You can do that with a tool like ngrok:

  1. 创建 ngrok 终结点Create an ngrok endpoint.
  2. 运行事件网格触发器函数Run the Event Grid trigger function.
  3. 创建事件网格订阅,用于向 ngrok 终结点发送事件。Create an Event Grid subscription that sends events to the ngrok endpoint.
  4. 触发事件Trigger an event.

完成测试后,可以更新终结点,将同一订阅用于生产。When you're done testing, you can use the same subscription for production by updating the endpoint. 使用 az eventgrid event-subscription update Azure CLI 命令。Use the az eventgrid event-subscription update Azure CLI command.

创建 ngrok 终结点Create an ngrok endpoint

ngrok 下载 ngrok.exe,然后使用以下命令运行该工具:Download ngrok.exe from ngrok, and run with the following command:

ngrok http -host-header=localhost 7071

之所以需要 -host-header 参数,是因为函数运行时运行于 localhost 时,预期接收来自 localhost 的请求。The -host-header parameter is needed because the functions runtime expects requests from localhost when it runs on localhost. 7071 是在本地运行运行时所用的默认端口号。7071 is the default port number when the runtime runs locally.

该命令创建如下所示的输出:The command creates output like the following:

Session Status                online
Version                       2.2.8
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://263db807.ngrok.io -> localhost:7071
Forwarding                    https://263db807.ngrok.io -> localhost:7071

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

请为事件网格订阅使用 https://{subdomain}.ngrok.io URL。You'll use the https://{subdomain}.ngrok.io URL for your Event Grid subscription.

运行事件网格触发器函数Run the Event Grid trigger function

事件网格不会对 ngrok URL 进行特殊处理,因此,创建订阅时,函数必须在本地运行。The ngrok URL doesn't get special handling by Event Grid, so your function must be running locally when the subscription is created. 否则不会发送验证响应,并且订阅创建将会失败。If it isn't, the validation response doesn't get sent and the subscription creation fails.

创建订阅Create a subscription

创建想要测试的类型的事件网格订阅,并在其中指定你的 ngrok 终结点。Create an Event Grid subscription of the type you want to test, and give it your ngrok endpoint.

对于 Functions 2.x,请使用以下终结点模式:Use this endpoint pattern for Functions 2.x:

https://{SUBDOMAIN}.ngrok.io/runtime/webhooks/eventgrid?functionName={FUNCTION_NAME}

对于 Functions 1.x,请使用以下终结点模式:Use this endpoint pattern for Functions 1.x:

https://{SUBDOMAIN}.ngrok.io/admin/extensions/EventGridExtensionConfig?functionName={FUNCTION_NAME}

{FUNCTION_NAME} 参数必须是在 FunctionName 特性中指定的名称。The {FUNCTION_NAME} parameter must be the name specified in the FunctionName attribute.

下面是使用 Azure CLI 的示例:Here's an example using the Azure CLI:

az eventgrid event-subscription create --resource-id /subscriptions/aeb4b7cb-b7cb-b7cb-b7cb-b7cbb6607f30/resourceGroups/eg0122/providers/Microsoft.Storage/storageAccounts/egblobstor0122 --name egblobsub0126 --endpoint https://263db807.ngrok.io/runtime/webhooks/eventgrid?functionName=EventGridTrigger

有关如何创建订阅的信息,请参阅本文前面所述的创建订阅For information about how to create a subscription, see Create a subscription earlier in this article.

触发事件Trigger an event

触发一个事件,以便向 ngrok 终结点生成 HTTP 流量。Trigger an event that will generate HTTP traffic to your ngrok endpoint. 例如,如果创建了 Blob 存储订阅,请上传或删除一个 Blob。For example, if you created a blob storage subscription, upload or delete a blob.

事件网格触发器函数将会执行,并显示类似于以下示例的日志:The Event Grid trigger function executes and shows logs similar to the following example:

事件网格触发器函数日志示例

将 HTTP 触发器用作事件网格触发器Use an HTTP trigger as an Event Grid trigger

事件网格事件以 HTTP 请求的形式接收,因此,可以使用 HTTP 触发器而不是事件网格触发器来处理事件。Event Grid events are received as HTTP requests, so you can handle events by using an HTTP trigger instead of an Event Grid trigger. 使用 HTTP 触发器的可能原因之一是能够更好地控制调用函数的终结点 URL。One possible reason for doing that is to get more control over the endpoint URL that invokes the function. 另一个原因是需要以 CloudEvents 架构接收事件。Another reason is when you need to receive events in the CloudEvents schema. 目前,事件网格触发器不支持 CloudEvents 架构。Currently, the Event Grid trigger doesn't support the CloudEvents schema. 本部分中的示例显示了有关事件网格架构和 CloudEvents 架构问题的解决方案。The examples in this section show solutions for both Event Grid schema and CloudEvents schema.

如果使用 HTTP 触发器,必须编写代码来指定事件网格触发器自动执行的操作:If you use an HTTP trigger, you have to write code for what the Event Grid trigger does automatically:

  • 将验证响应发送到订阅验证请求Sends a validation response to a subscription validation request.
  • 针对请求正文中包含的事件数组的每个元素调用该函数一次。Invokes the function once per element of the event array contained in the request body.

有关用于在本地调用函数或者在 Azure 中运行函数的 URL 的信息,请参阅 HTTP 触发器绑定参考文档For information about the URL to use for invoking the function locally or when it runs in Azure, see the HTTP trigger binding reference documentation

事件网格架构Event Grid schema

以下 HTTP 触发器的示例 C# 代码可模拟事件网格触发器的行为。The following sample C# code for an HTTP trigger simulates Event Grid trigger behavior. 将此示例用于以事件网格架构传递的事件。Use this example for events delivered in the Event Grid schema.

[FunctionName("HttpTrigger")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")]HttpRequestMessage req,
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    var messages = await req.Content.ReadAsAsync<JArray>();

    // If the request is for subscription validation, send back the validation code.
    if (messages.Count > 0 && string.Equals((string)messages[0]["eventType"],
        "Microsoft.EventGrid.SubscriptionValidationEvent",
        System.StringComparison.OrdinalIgnoreCase))
    {
        log.LogInformation("Validate request received");
        return req.CreateResponse<object>(new
        {
            validationResponse = messages[0]["data"]["validationCode"]
        });
    }

    // The request is not for subscription validation, so it's for one or more events.
    foreach (JObject message in messages)
    {
        // Handle one event.
        EventGridEvent eventGridEvent = message.ToObject<EventGridEvent>();
        log.LogInformation($"Subject: {eventGridEvent.Subject}");
        log.LogInformation($"Time: {eventGridEvent.EventTime}");
        log.LogInformation($"Event data: {eventGridEvent.Data.ToString()}");
    }

    return req.CreateResponse(HttpStatusCode.OK);
}

以下 HTTP 触发器的示例 JavaScript 代码可模拟事件网格触发器的行为。The following sample JavaScript code for an HTTP trigger simulates Event Grid trigger behavior. 将此示例用于以事件网格架构传递的事件。Use this example for events delivered in the Event Grid schema.

module.exports = function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    var messages = req.body;
    // If the request is for subscription validation, send back the validation code.
    if (messages.length > 0 && messages[0].eventType == "Microsoft.EventGrid.SubscriptionValidationEvent") {
        context.log('Validate request received');
        var code = messages[0].data.validationCode;
        context.res = { status: 200, body: { "ValidationResponse": code } };
    }
    else {
        // The request is not for subscription validation, so it's for one or more events.
        // Event Grid schema delivers events in an array.
        for (var i = 0; i < messages.length; i++) {
            // Handle one event.
            var message = messages[i];
            context.log('Subject: ' + message.subject);
            context.log('Time: ' + message.eventTime);
            context.log('Data: ' + JSON.stringify(message.data));
        }
    }
    context.done();
};

事件处理代码通过 messages 数组进入循环内部。Your event-handling code goes inside the loop through the messages array.

CloudEvents 架构CloudEvents schema

以下 HTTP 触发器的示例 C# 代码可模拟事件网格触发器的行为。The following sample C# code for an HTTP trigger simulates Event Grid trigger behavior. 将此示例用于以 CloudEvents 架构传递的事件。Use this example for events delivered in the CloudEvents schema.

[FunctionName("HttpTrigger")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    var requestmessage = await req.Content.ReadAsStringAsync();
    var message = JToken.Parse(requestmessage);

    if (message.Type == JTokenType.Array)
    {
        // If the request is for subscription validation, send back the validation code.
        if (string.Equals((string)message[0]["eventType"],
        "Microsoft.EventGrid.SubscriptionValidationEvent",
        System.StringComparison.OrdinalIgnoreCase))
        {
            log.LogInformation("Validate request received");
            return req.CreateResponse<object>(new
            {
                validationResponse = message[0]["data"]["validationCode"]
            });
        }
    }
    else
    {
        // The request is not for subscription validation, so it's for an event.
        // CloudEvents schema delivers one event at a time.
        log.LogInformation($"Source: {message["source"]}");
        log.LogInformation($"Time: {message["eventTime"]}");
        log.LogInformation($"Event data: {message["data"].ToString()}");
    }

    return req.CreateResponse(HttpStatusCode.OK);
}

以下 HTTP 触发器的示例 JavaScript 代码可模拟事件网格触发器的行为。The following sample JavaScript code for an HTTP trigger simulates Event Grid trigger behavior. 将此示例用于以 CloudEvents 架构传递的事件。Use this example for events delivered in the CloudEvents schema.

module.exports = function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    var message = req.body;
    // If the request is for subscription validation, send back the validation code.
    if (message.length > 0 && message[0].eventType == "Microsoft.EventGrid.SubscriptionValidationEvent") {
        context.log('Validate request received');
        var code = message[0].data.validationCode;
        context.res = { status: 200, body: { "ValidationResponse": code } };
    }
    else {
        // The request is not for subscription validation, so it's for an event.
        // CloudEvents schema delivers one event at a time.
        var event = JSON.parse(message);
        context.log('Source: ' + event.source);
        context.log('Time: ' + event.eventTime);
        context.log('Data: ' + JSON.stringify(event.data));
    }
    context.done();
};

后续步骤Next steps