【问题标题】:How to add function.json to existing .NET function 2.0如何将 function.json 添加到现有的 .NET 函数 2.0
【发布时间】:2019-01-31 18:02:12
【问题描述】:

当我使用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"
    }
  ]
}

以前的httpTrigger函数

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");
        }
    }
}

新的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");
        }
    }
}

【问题讨论】:

  • C#(注意不是 C# 脚本)函数的 function.json 文件应该由构建过程生成,因此您不必手动添加。你能澄清一下你在哪里添加function.json文件(它和你的host.json在同一个目录吗?别处?),什么时候? (预构建?您没有在 /bin/output/MyHttpTrigger/ post-build 中看到 function.json 并且正在添加它吗?)
  • 当我使用 C# 使用 func new 不带 --csx 参数创建函数时,我尝试在host.json 附近的 function.json 附近添加函数,我也尝试向此添加新目录函数并在run.cs附近添加function.json(因为默认情况下没有为函数创建目录),但是当我使用--csx参数时,新目录是用function.json创建的......
  • 感谢您提供此信息。回复为答案。

标签: c# azure azure-functions serverless


【解决方案1】:

简答 构建过程负责根据您附加到方法的属性为您在 .cs 文件中定义的函数生成 function.json 文件。 Functions 文档中有几个示例,例如。 a BlobTrigger function in C#. 您不需要添加自己的function.json

请参阅长答案部分,详细了解幕后工作原理。如果您看到针对已编译 C# 函数描述的所有预期构建输出,并且函数运行时仍未找到任何函数,请检查您是否在函数应用结构的顶级目录中运行 func start --build

长答案 您描述的行为是设计使然。听起来您已经习惯了脚本语言使用的 Functions 的文件夹结构,例如 .csx(C# 脚本)文件。这是一个定义两个函数的示例,MyFunctionMySecondFunction

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

最初,Functions 运行时只能识别这种文件夹结构,而 C# 函数只能用 C# 脚本编写。 (original blog announcement | MSDN magazine article) 后来添加了常规的 C# 支持。我将常规 C# 称为 compiled 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 andFunctionAppin 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 Functions 运行时启动时(例如 func host start),它不会查看 FunctionApp 来确定存在哪些函数并连接绑定。它看着FunctionApp/bin/Debug/net461/MyFunction

唯一的区别在于每个函数的文件夹。在编译的 C# 函数应用中,每个函数的文件夹都缺少 C# 脚本函数应用中的 .csx 文件。仔细查看编译后的 C# 函数应用的 FunctionApp/bin/Debug/net461/MyFunction 文件夹中的 function.json,您会看到如下内容:

{
  "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"
}

与为 C# 脚本函数创建的 function.json 相比,编译后的 C# 函数的 function.json 有一些额外的字段。以下是每个函数对函数运行时的指示:

  • generatedBy:这个function.json是编译时生成的,不是手写的
  • configurationSource:这个function.json 是从 C# 属性生成的
  • scriptFile:包含与此函数对应的编译代码的 DLL 的位置,相对于此 function.json 文件的位置
  • entryPoint: 已编译DLL中函数的方法签名

长话短说,编译后的 C# 函数应用在运行时依赖于与 C# 脚本函数应用相同的文件夹结构,但它是由构建过程生成的,而不是由开发人员构建的。使用编译后的 C# 编写函数应用的开发人员通过 C# 属性定义其绑定,将 function.json 生成留给构建过程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 2019-12-07
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 2016-12-28
    • 2012-03-29
    相关资源
    最近更新 更多