You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Isolated模式BlobTrigger触发但未执行函数代码求助

.NET 8 Azure Function BlobTrigger 触发器日志显示执行成功但函数代码未运行

我此前使用.NET 6创建的Azure Function(BlobTrigger)运行完全正常,迁移至.NET 8后遇到问题:触发器日志显示已成功执行,但实际并未运行函数代码。

已尝试的排查步骤:

  • 从零创建新的.NET 8函数应用排除依赖问题
  • 更换自定义连接字符串为默认AzureWebJobsStorage
  • 在启动代码中配置AddBlobServiceClient作为AzureClient
  • 检查日志确认触发器执行情况
  • 更换测试文件(含空格名称文件)
  • 调整依赖包版本

存储账户为StorageV2(通用v2),在.NET 6环境下运行正常,排除存储账户本身问题。

项目依赖配置

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Azure.Data.AppConfiguration" Version="1.4.1" />
    <PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.20.1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs" Version="6.2.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.21.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="7.2.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
  </ItemGroup>
</Project>

启动代码

using Azure.Data.AppConfiguration;
using Azure.Extensions.AspNetCore.Configuration.Secrets;
using Azure.Identity;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Identity.Client;

namespace ViyaTransferService
{
    public record ConfidentialClientAppScopes(string[] Scopes);

    internal class Program
    {
        public static async Task Main()
        {
            var config = InitializeConfiguration(new ConfigurationBuilder());

            var host = ConfigureHostServices(config)
                .Build();

            Console.WriteLine($"running host");
            await host.RunAsync();
        }

        public static IHostBuilder ConfigureHostServices(IConfiguration config)
        {
            Console.WriteLine($"loading services");
            return new HostBuilder()
                .ConfigureFunctionsWorkerDefaults()
                .ConfigureFunctionsWebApplication()
                .ConfigureAppConfiguration(config => { config.AddUserSecrets<Program>(optional: true, reloadOnChange: false); })
                .ConfigureServices(services =>
                {
                    services.AddApplicationInsightsTelemetryWorkerService();
                    services.ConfigureFunctionsApplicationInsights();
                    services.AddScoped(x => new ConfigurationClient(Environment.GetEnvironmentVariable("AppConfigConnectionString")));
                    services.AddScoped<IFileTransferService, FileTransferService>();

                    services.AddSingleton(x => ConfidentialClientApplicationBuilder...
                        .Build()
                    );

                    services.AddSingleton(x => new ConfidentialClientAppScopes(...).Append("/.default").ToArray());

                    services.AddAzureClients(clientBuilder =>
                    {
                        clientBuilder.AddBlobServiceClient(Environment.GetEnvironmentVariable("ViyaStorageConnectionString"));
                    });

                    services.AddLogging();
                })
                .ConfigureLogging(logging =>
                {
                    ...
                });
        }

        static IConfiguration InitializeConfiguration(IConfigurationBuilder builder)
        {
            string? startupenv = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT");
            Console.WriteLine($"startupenv: {startupenv}");

            string cs = Environment.GetEnvironmentVariable("AppConfigConnectionString");
            builder.AddAzureAppConfiguration(cs);

            if (startupenv != "Development" && !string.IsNullOrEmpty(keyVaultUrl) && !string.IsNullOrEmpty(clientId))
            {
                Console.WriteLine($"loading keyvault");
                builder.AddAzureKeyVault(...);
            }

            Console.WriteLine($"loaded config");
            return builder.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true).AddEnvironmentVariables().Build();
        }
    }
}

解决方案

1. 调整HostBuilder配置顺序

在.NET 8孤立模型中,ConfigureFunctionsWebApplication需要放在ConfigureFunctionsWorkerDefaults之前,否则会覆盖Worker的触发器绑定配置,导致函数无法正确触发。修改后的ConfigureHostServices:

public static IHostBuilder ConfigureHostServices(IConfiguration config)
{
    Console.WriteLine($"loading services");
    return new HostBuilder()
        .ConfigureFunctionsWebApplication()
        .ConfigureFunctionsWorkerDefaults()
        .ConfigureAppConfiguration(config => { config.AddUserSecrets<Program>(optional: true, reloadOnChange: false); })
        // 后续配置保持不变
}

2. 确认BlobTrigger的Connection参数配置

确保BlobTrigger特性中指定了正确的连接字符串名称,例如使用自定义连接字符串时:

[Function("BlobTriggerFunction")]
public async Task Run(
    [BlobTrigger("your-container/{name}", Connection = "ViyaStorageConnectionString")] BlobClient blobClient,
    string name,
    FunctionContext context)
{
    // 函数代码
}

3. 检查host.json配置

确保extensions.blobs配置正确,避免异常的并行设置或其他限制:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensions": {
    "blobs": {
      "maxDegreeOfParallelism": 16,
      "batchSize": 10
    }
  }
}

4. 调整配置加载顺序

在InitializeConfiguration中,先加载本地配置和环境变量,再添加Azure App Configuration,确保本地开发的连接字符串不会被覆盖:

static IConfiguration InitializeConfiguration(IConfigurationBuilder builder)
{
    string? startupenv = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT");
    Console.WriteLine($"startupenv: {startupenv}");

    // 先加载本地配置和环境变量
    builder.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
           .AddEnvironmentVariables();

    string cs = Environment.GetEnvironmentVariable("AppConfigConnectionString");
    if (!string.IsNullOrEmpty(cs))
    {
        builder.AddAzureAppConfiguration(cs);
    }

    if (startupenv != "Development" && !string.IsNullOrEmpty(keyVaultUrl) && !string.IsNullOrEmpty(clientId))
    {
        Console.WriteLine($"loading keyvault");
        builder.AddAzureKeyVault(...);
    }

    Console.WriteLine($"loaded config");
    return builder.Build();
}

5. 确认函数类和方法的访问修饰符

函数类和函数方法必须是public,孤立模型下无法发现internal或private的函数:

public class BlobTriggerFunction
{
    [Function("BlobTriggerFunction")]
    public async Task Run(...)
    {
        // 函数代码
    }
}

6. 捕获启动时的异常

在Main方法中添加异常捕获,排查是否有服务注入失败导致函数无法初始化:

public static async Task Main()
{
    try
    {
        var config = InitializeConfiguration(new ConfigurationBuilder());
        var host = ConfigureHostServices(config).Build();
        Console.WriteLine($"running host");
        await host.RunAsync();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Host initialization failed: {ex.Message}");
        Console.WriteLine(ex.StackTrace);
        throw;
    }
}

内容的提问来源于stack exchange,提问作者Dave Green

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 14:41:00