Как добавить function.json в существующую функцию .NET 2.0 - PullRequest
0 голосов
/ 31 января 2019

когда я добавляю новую функцию, используя func new --name MyHttpTrigger --template "HttpTrigger", в этой функции не создается function.json, а когда я пытался добавить ее в текущий каталог и запускать func start --build, я получаю эту ошибку:

Не найдено ни одной вакансии.Попробуйте сделать ваши классы и методы работы публичными.Если вы используете привязки расширений (например, хранилище Azure, ServiceBus, таймеры и т. Д.), Убедитесь, что вы вызвали метод регистрации расширений в своем коде запуска (например, builder.AddAzureStorage (), builder.AddServiceBus (), builder.AddTimers () и т. д.).

вы можете найти здесь мой function.json контент:

{
  "disabled": false,
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in"
    },
    {
      "name": "res",
      "type": "http",
      "direction": "out"
    }
  ]
}

Pervious httpTrigger function

namespace final
{
    public static class httpTrigger
    {
        [FunctionName("httpTrigger")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }
    }
}

NewФункция httpTrigger

namespace final
{
    public static class httpTrigger
    {
        public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }
    }
}

1 Ответ

0 голосов
/ 02 февраля 2019

Краткий ответ Процесс сборки заботится о создании файлов function.json для функций, которые вы определяете в своих файлах .cs на основе атрибутов, которые вы прикрепляете к своим методам.Есть несколько примеров в документации по функциям, напр. a Функция BlobTrigger в C #. Вам не нужно добавлять свои собственные function.json.

Подробную информацию о том, как это работает за кулисами, см. В разделе «Длинный ответ».Если вы видите все ожидаемые выходные данные сборки, описанные для скомпилированной функции C #, и среда выполнения функций по-прежнему не находит какие-либо функции, убедитесь, что вы запускаете func start --build для каталога верхнего уровня своей структуры приложения функции.

Длинный ответ Поведение, которое вы описываете, разработано.Похоже, вы привыкли к структуре папок функций, используемых языками сценариев, например, для файлов .csx (C # script).Вот пример, который определяет две функции, MyFunction и MySecondFunction:

FunctionApp
| - bin
| - MyFunction
| | - function.json
| | - run.csx
| - MySecondFunction
| | - function.json
| | - run.csx
| ...
| host.json
| local.settings.json

Изначально среда выполнения функций распознала только эту структуру папок, а функции C # могли быть написаны только в сценарии C #.( оригинальное объявление в блоге | статья в журнале MSDN ) Позже была добавлена ​​регулярная поддержка C #.Я буду ссылаться на обычный C # как скомпилированный C # , чтобы подчеркнуть различие между ним и скриптом C #.

Тот же пример, что и у скомпилированного приложения-функции C #, имеет структуру папок, подобную этой:

FunctionApp
| - bin
| - obj
| - host.json
| - local.settings.json
| - FunctionApp.csproj
| - MyFunction.cs
| - MySecondFunction.cs

Если вы соберете этот проект и развернете папку FunctionApp/bin, вы увидите что-то вроде этого:

FunctionApp
| - bin
| | - Debug
| | | - net461
| | | | - bin
| | | | - MyFunction
| | | | | - function.json
| | | | - MySecondFunction
| | | | | - function.json
| | | - host.json
| | | - local.settings.json
| | | - netstandard2.0
| | | | - …
| - obj
| - host.json
| - local.settings.json
| - FunctionApp.csproj
| - MyFunction.cs
| - MySecondFunction.cs

(папка netstandard2.0 будет содержать содержимое, аналогичное net461 папка; это просто разные цели построения фреймворка.)

Обратите внимание, что сходство между FunctionApp/bin/Debug/net461 in the compiled C# function app's folder structure and FunctionApp in the C# script app's folder structure. This is because the build process for C# (not C# script) function apps uses the attributes of the methods in the .cs files (ex. HttpTrigger`) определяет, какие функции были определены, и создает исходную структуру папок в качестве еевыходные данные сборки.

Когда запускается среда выполнения функций Azure (например, func host start), она не смотрит на FunctionApp, чтобы выяснить, какие функции существуют, и связать привязки.Это выглядит на FunctionApp/bin/Debug/net461/MyFunction.

Единственное отличие находится в папках для каждой функции.В скомпилированном приложении-функции C # каждой папке функции не хватает файла .csx в приложении-функции скрипта C #.Присмотритесь к function.json в папке FunctionApp/bin/Debug/net461/MyFunction приложения скомпилированной функции C #, и вы увидите что-то вроде этого:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.13",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "httpTrigger",
      "methods": [
        "post"
      ],
      "authLevel": "function",
      "name": "req"
    }
  ],
  "disabled": false,
  "scriptFile": "../bin/VSSample.dll",
  "entryPoint": "VSSample.HttpStart.Run"
}

По сравнению с function.json, созданным для функции сценария C #,function.json скомпилированной функции C # имеет несколько дополнительных полей.Вот что каждый указывает на время выполнения функций:

  • generatedBy: это function.json было сгенерировано во время компиляции, а не написано от руки
  • configurationSource: это function.json былогенерируется из атрибутов C #
  • scriptFile: расположение библиотеки DLL, содержащей скомпилированный код, соответствующий этой функции, относительно расположения этого function.json файла
  • entryPoint: сигнатура методафункция в скомпилированной DLL

Короче говоря, скомпилированное приложение-функция C # во время выполнения опирается на ту же структуру папок, что и приложение-функцию скрипта C #, но оно генерируется процессом сборки, а не создаетсяразработчиком.Разработчик, пишущий приложение функции в скомпилированном C #, определяет свои привязки через атрибуты C #, оставляя генерацию function.json процессу сборки.

...