Атрибут «Атрибут таблицы» является атрибутом веб-заданий и не поддерживается в .СЕТЕВОЙ Работник, Изолированный Процесс

#c# #azure-functions #azure-web-app-service

Вопрос:

Я переношу некоторые функции с netcore 3.1 на net5, чтобы использовать изолированную модель. Однако я столкнулся с этой несовместимостью, которую я не решил; документация не привела меня к поиску решения. Речь идет об использовании функции Azure для помещения строки в таблицу хранения, этот фрагмент кода работает идеально:

 // netcoreapp3.1, works OK
[FunctionName("PlaceOrder")]
public static async Task<IActionResult> Run(
   [HttpTrigger(AuthorizationLevel.Anonymous, "post")] 
   OrderPlacement orderPlacement,
   
   [Table("Orders")] IAsyncCollector<Order> orders)
{
   await orders.AddAsync(new Order {
       PartitionKey = "US",
       RowKey = Guid.NewGuid().ToString(),
       CustomerName = orderPlacement.CustomerName,
       Product = orderPlacement.Product
   });
   return new OkResult();
}
 

Попытка сделать это в net5 была бы очень похожа на следующую:

 // net5.0 approach
[Function("PlaceOrder")]
public static async Task<IActionResult> Run(

   [HttpTrigger(AuthorizationLevel.Anonymous, "post")]
   HttpRequestData req,

   [Table("Orders")] IAsyncCollector<Order> orders)
{
   var orderPlacement = await req.ReadFromJsonAsync<OrderPlacement>();

   await orders.AddAsync(new Order {
       PartitionKey = "US",
       RowKey = Guid.NewGuid().ToString(),
       CustomerName = orderPlacement.CustomerName,
       Product = orderPlacement.Product
   });
   return new OkResult();
}
 

Но строка привязки таблицы указывает на ошибку: атрибут «Атрибут таблицы» является атрибутом веб-заданий и не поддерживается в .СЕТЕВОЙ работник (Изолированный процесс). — Каков правильный эквивалент?

Комментарии:

1. Там его нет. Это связано с тем, что функции Azure-это полный бардак несовместимости, и вам следует любой ценой избегать «обновления» до версии 5. Надеюсь, к .NET 6 они разрешат эту чушь, но, к сожалению, я бы не стал задерживать дыхание.

Ответ №1:

Вы должны использовать Microsoft.Azure.Functions.Worker.Extensions.* пакет для функции Azure .net 5.

Вы можете прочитать эту официальную документацию для получения дополнительной информации.

введите описание изображения здесь

Поэтому для привязки таблицы используйте Microsoft.Azure.Functions.Worker.Extensions.Storage пакет, а также используйте TableOutput атрибут для привязки.

Как показано ниже:

     [Function("TableFunction")]
    [TableOutput("OutputTable", Connection = "AzureWebJobsStorage")]
    public static MyTableData Run([QueueTrigger("table-items")] string input,
        [TableInput("MyTable", "MyPartition", "{queueTrigger}")] MyTableData tableInput,
        FunctionContext context)
    {
        var logger = context.GetLogger("TableFunction");

        logger.LogInformation($"PK={tableInput.PartitionKey}, RK={tableInput.RowKey}, Text={tableInput.Text}");

        return new MyTableData()
        {
            PartitionKey = "queue",
            RowKey = Guid.NewGuid().ToString(),
            Text = $"Output record with rowkey {input} created at {DateTime.Now}"
        };
    }
 

Вы можете проверить образец на наличие различных поддерживаемых привязок здесь.

Комментарии:

1. Это может быть стратегическим решением в сочетании с большим количеством функций. Хотя я не вижу, где в таблице записывается новая строка. Проблема в том, что через одну запись передается объект, часть идентификатора, и функция записывает его в таблицу Azure. Я знаю, что есть решение, — Вещи в коде не эволюционируют, чтобы быть меньше, чем их предшественник. Спасибо за внимание.

2. Новая строка будет записана в OutputTable соответствии с определением в TableOutput атрибуте. Вы можете соответствующим образом обновить значение.

Ответ №2:

Решение-это одна строка. Эквивалентом является следующее:

 public static class PlaceOrder
{
    [Function("PlaceOrder")]
    [TableOutput("Orders")]
    public static async Task<Order> TableOutput(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
    {
        var orderPlacement = await req.ReadFromJsonAsync<OrderPlacement>();
        return new Order {
            PartitionKey = "US",
            RowKey = Guid.NewGuid().ToString(),
            CustomerName = orderPlacement.CustomerName,
            Product = orderPlacement.Product
        };
    }
}
 

Ответ №3:

У меня была та же проблема, и я добавил следующие ссылки в свой файл *.csproj:

 <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.5.1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.0.4" OutputItemType="Analyzer" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
</ItemGroup>