Функция Azure, запускаемая с помощью BLOB-объектов: BLOB-объект нельзя привязать к первому аргументу функции Azure в среде Azure

Я хочу создать простую функцию Azure, которая запускается при загрузке большого двоичного объекта.

Функция работает правильно, как и ожидалось, когда я запускаю ее локально. Проблема в том, что когда я публикую код с опцией публикации Visual Studio 2022, я получаю исключение, и функция вообще не выполняется. Насколько я понял, проблема в том, что аргумент функции "Stream" по какой-то странной причине не может быть привязан.

Это исключение, которое я получаю:

Ошибка преобразования 1 входного параметра для функции «BlobTriggeredFunction»: невозможно преобразовать входной параметр «поток» в тип «System.IO.Stream» из типа «Microsoft.Azure.Functions.Worker.Grpc.Messages.GrpcModelBindingData». Ошибка: System.FormatException: настройки должны иметь форму «имя=значение». в Azure.Storage.StorageConnectionString.<>c.b__67_0 (ошибка строки) в Azure.Storage.StorageConnectionString.ParseStringIntoSettings (String ConnectionString, ошибка Action1 error) at Azure.Storage.StorageConnectionString.ParseCore(String connectionString, StorageConnectionString& accountInformation, Action1) в Azure.Storage.StorageConnectionString.Parse(String ConnectionString) в Azure.Storage.Blobs.BlobServiceClient..ctor (String ConnectionString, параметры BlobClientOptions) в Microsoft.Azure.Functions.Worker.BlobStorageBindingOptions.CreateClient() в D:\a_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\Config\BlobStorageBindingOptions.cs:строка 35 в Microsoft.Azure.Functions.Worker.BlobStorageConverter.CreateBlobContainerClient(String ConnectionName, StringContainerName) в D:\a_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:строка 253 в Microsoft.Azure.Functions.Worker.BlobStorageConverter.ConvertModelBindingDataAsync(Type targetType, BlobBindingData blobData) в D:\a_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:строка 118 в Microsoft.Azure.Functions.Worker.BlobStorageConverter.ConvertFromBindingDataAsync(ConverterContext context, ModelBindingData modelBindingData) в D:\a_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:строка 63

Это код функции:


public class BlobTriggeredFunction(ILogger<BlobTriggeredFunction> logger)
{
    [Function(nameof(BlobTriggeredFunction))]
    public async Task Run([BlobTrigger("email-attachments/{name}", Connection = "BlobStorageConnectionString")] Stream stream, string name)
    {
        using var blobStreamReader = new StreamReader(stream);
        var content = await blobStreamReader.ReadToEndAsync();
        logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {content}");
    }
}

Это настройка в Program.cs:

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureAppConfiguration((hostContext, config) =>
    {
        config.AddJsonFile("host.json");
        if (hostContext.HostingEnvironment.IsDevelopment())
        {
            config.AddJsonFile("local.settings.json");
            config.AddUserSecrets<Program>();
        }
    })
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();

секреты.json:

{
  "BlobStorageConnectionString": "xxxxxxxxxxxxxxxxxxxxxxx",
  "BlobStorageConnectionString:blob": "https://xxxxxxxxxxxxxxx.blob.core.windows.net/",
  "BlobStorageConnectionString:queue": "https://xxxxxxxxxxxxxxx.queue.core.windows.net/"
}

Я попытался изменить аргумент «Stream» на byte[] или строку, но ничего из этого не помогло. Я не ожидаю, что проблема в строке подключения, поскольку функция срабатывает, когда я загружаю большой двоичный объект, но его невозможно обработать. Худшая проблема заключается в том, что это происходит только в среде Azure, когда я публикую код. Он отлично работает в локальной среде.

Это изолированная функция Azure .NET8?

Pravallika KV 19.04.2024 10:41

Да. Это изолированная функция Azure dotnet core 8.

Charlemagne 19.04.2024 11:37

local.settings.json используется только в локальной среде в отладочной сборке. Кроме того, файл local.settings.json не копируется для публикации выходных данных и не существует при развертывании приложения на портале Azure.

Charlemagne 20.04.2024 09:51
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
230
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я создал образец функции Azure Blob Trigger и могу запустить развернутую функцию Azure на портале.

Фрагмент кода:

  • Функция.cs:
public Function1(ILogger<Function1> logger)
{
    _logger = logger;
}

[Function(nameof(Function1))]
public async Task Run([BlobTrigger("sampleitems/{name}", Connection = "storageconnection")] Stream stream, string name)
{
    using var blobStreamReader = new StreamReader(stream);
    var content = await blobStreamReader.ReadToEndAsync();
    _logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {content}");
}

Если «StorageAccountConnectionString» определен как секрет пользователя в secrets.json, вам необходимо добавить секреты пользователя в файл program.cs.

.ConfigureAppConfiguration(config => { config.AddUserSecrets<YourFunctionName>(optional: true, reloadOnChange: false); })

Программа.cs:

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureAppConfiguration( config =>
    {
        config.AddUserSecrets<Function1>(optional: true, reloadOnChange: false);
    })
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();
  • Добавьте строку подключения в качестве переменной среды в Azure function App=>Settings=>Environment Variables=>New Application Setting.

  • Развернули функцию Blob Trigger в Azure.

Портал:

  • Возможность успешного запуска функции на портале:

Использованная литература:

  1. GitHub Issue1

  2. GitHub Issue2

Секреты пользователя следует использовать только в локальной среде и отладочной сборке. Переменные среды используются в сборке выпуска и при развертывании приложения на портале Azure.

Charlemagne 20.04.2024 09:53

Я понятия не имею, почему переменные среды включены по умолчанию в вашем случае, а не в моем.

Charlemagne 20.04.2024 09:53
Ответ принят как подходящий

Проблема заключалась в том, что я не добавил переменные среды в Program.cs. Переменные среды используются на портале Azure.

.ConfigureAppConfiguration( ( hostContext, config ) =>
{
    config.AddJsonFile( "host.json" );

    if (hostContext.HostingEnvironment.IsDevelopment())
    {
        config.AddJsonFile("local.settings.json");
        config.AddUserSecrets<ArchiveManagerFunction>(optional: true, reloadOnChange: false);
    }

    config.AddEnvironmentVariables();
} )

Итак, решение моей проблемы было в этой строке кода:

config.AddEnvironmentVariables();

Другие вопросы по теме