C# 将blob名称与具有输入绑定的函数变量进行模式匹配

C# 将blob名称与具有输入绑定的函数变量进行模式匹配,c#,azure-functions,azure-storage-blobs,C#,Azure Functions,Azure Storage Blobs,根据,在配置blob触发器时,可以利用blob名称上的模式匹配将路径的部分映射到函数eg中的变量 [FunctionName("BlobTriggered")] public static void BlobTriggered( [BlobTrigger("myContainer/{name}.{extension}")] Stream myBlob, string name, string extension, TraceWriter log)

根据,在配置blob触发器时,可以利用blob名称上的模式匹配将路径的部分映射到函数eg中的变量

[FunctionName("BlobTriggered")]        
public static void BlobTriggered(
    [BlobTrigger("myContainer/{name}.{extension}")] Stream myBlob,
    string name,
    string extension,
    TraceWriter log)
{
    // Given the blob path "myContainer/myBlob.png":
    // name == "myBlob"
    // extension == "png"
}
我已经对此进行了测试,它在我的用例中运行得非常出色,但是由于
BlobTrigger
触发延迟较大(通常超过5分钟),它不是一个可行的选择。因此,我希望按照以下建议将其作为事件网格触发器:

当您在消费计划中使用blob触发器时,处理新blob可能会延迟10分钟。此延迟发生在功能应用程序空闲时。函数应用程序运行后,将立即处理blob。要避免此冷启动延迟,请使用启用了“始终打开”的应用程序服务计划,或使用事件网格触发器

有没有办法从输入绑定而不是触发器获得相同的模式匹配行为

在我的特定情况下,我为blob创建设置了一个
EventGrid
订阅,该订阅运行一个orchestrator函数,调用活动函数来读取和解析blob:

[FunctionName("NewBlobCreated")]
public static async Task NewBlobCreated(
    [EventGridTrigger]EventGridEvent eventGridEvent,
    [OrchestrationClient]DurableOrchestrationClient starter,
    ILogger log)
{
    // Start our orchestrator function to read the file
    string instanceId = await starter.StartNewAsync(
        "OrchestrateBlobReader",
        eventGridEvent);
}

// Orchestrator function
[FunctionName("OrchestrateBlobReader")]
public static async Task OrchestrateBlobReader(
    [OrchestrationTrigger] DurableOrchestrationContext context,
    ILogger log)
{
    var eventGridEvent = context.GetInput<EventGridEvent>();
    var parsedBlob = await context.CallActivityAsync<string>("ReadBlob", eventGridEvent.Data);        
    ...
}

[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
    [ActivityTrigger] JObject eventData,
    [Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
    ILogger log)
{
    using (var blobStream = await blob.OpenReadAsync())
    {
        // Blob is able to be read from blobStream here
        ...
    }
}
问题是,我找不到任何方法将
扩展
参数绑定到
Blob
输入绑定,就像我为
BlobTrigger
所做的那样-尤其是将路径绑定到
EventGridEvent
提供的url 以
eventData
JObject
的形式


在这种情况下,是否可以实现相同的模式匹配功能?或者我必须自己解析路径字符串来提取相关信息吗?

在查看了blob触发器绑定的源代码之后,我的“快速而肮脏”解决方案是挖掘触发器用来将路径和模式映射到字典的底层

更新的
ReadBlob
函数如下:

// So we can access the BindingTemplateSource class
using Microsoft.Azure.WebJobs.Host.Bindings.Path;

[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
    [ActivityTrigger] JObject eventData,
    [Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
    ILogger log)
{
    // Define the pattern to match
    var blobPattern = "myContainer/{name}.{extension}";
    // Create a BindingTemplateSource from the pattern string
    var patternTemplate = BindingTemplateSource.FromString(blobPattern);
    // Use this BindingTemplateSource to create the binding data
    // This returns a IReadOnlyDictionary<string, object> with the parameters mapped
    var parameters = patternTemplate.CreateBindingData($"{blob.Container.Name}/{blob.Name}");
    // Assuming blob path was "myContainer/myBlob.png":
    // Parameters are objects so we need to ToString() them
    var name = parameters["name"].ToString(); // name == "myBlob"
    var extension = parameters["extension"].ToString(); // extension == "png"

    if (extension.Equals("txt", StringComparison.OrdinalIgnoreCase))
    { ... }
    else if (extension.Equals("png", StringComparison.OrdinalIgnoreCase))
    { 
        // This executes now!
    }
    else
    { ... }
}
//因此我们可以访问BindingTemplateSource类
使用Microsoft.Azure.WebJobs.Host.Bindings.Path;
[FunctionName(“ReadBlob”)]
公共静态异步任务ReadBlob(
[ActivityTrigger]作业对象事件数据,
[Blob(“{data.url}”,FileAccess.Read)]CloudBlockBlob Blob,
ILogger日志)
{
//定义要匹配的模式
var blobPattern=“myContainer/{name}.{extension}”;
//从模式字符串创建BindingTemplateSource
var patternTemplate=BindingTemplateSource.FromString(blobPattern);
//使用此BindingTemplateSource创建绑定数据
//这将返回一个带有映射参数的IReadOnlyDictionary
var参数=patternTemplate.CreateBindingData($“{blob.Container.Name}/{blob.Name}”);
//假设blob路径为“myContainer/myBlob.png”:
//参数是对象,所以我们需要将它们转换为字符串()
var name=parameters[“name”].ToString();//name==“myBlob”
var extension=parameters[“extension”].ToString();//extension==“png”
if(extension.Equals(“txt”,StringComparison.OrdinalIgnoreCase))
{ ... }
else if(extension.Equals(“png”,StringComparison.OrdinalIgnoreCase))
{ 
//现在执行!
}
其他的
{ ... }
}

然后,这个功能可能会被包装在一个框架中,其中参数映射到函数上的输出绑定,就像
BlobTrigger
为最优雅的解决方案所做的那样,但是像这样将其黑客化到函数中可以实现我短期需要的功能

谢谢提醒。我不得不等待48小时的暂停,现在还没有机会回到这个话题上来
// So we can access the BindingTemplateSource class
using Microsoft.Azure.WebJobs.Host.Bindings.Path;

[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
    [ActivityTrigger] JObject eventData,
    [Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
    ILogger log)
{
    // Define the pattern to match
    var blobPattern = "myContainer/{name}.{extension}";
    // Create a BindingTemplateSource from the pattern string
    var patternTemplate = BindingTemplateSource.FromString(blobPattern);
    // Use this BindingTemplateSource to create the binding data
    // This returns a IReadOnlyDictionary<string, object> with the parameters mapped
    var parameters = patternTemplate.CreateBindingData($"{blob.Container.Name}/{blob.Name}");
    // Assuming blob path was "myContainer/myBlob.png":
    // Parameters are objects so we need to ToString() them
    var name = parameters["name"].ToString(); // name == "myBlob"
    var extension = parameters["extension"].ToString(); // extension == "png"

    if (extension.Equals("txt", StringComparison.OrdinalIgnoreCase))
    { ... }
    else if (extension.Equals("png", StringComparison.OrdinalIgnoreCase))
    { 
        // This executes now!
    }
    else
    { ... }
}