当我使用func new --name MyHttpTrigger --template "HttpTrigger"
添加新功能时,此函数中没有创建function.json
,并且当我尝试将其添加到当前目录并运行func start --build
时,出现此错误:
您可以在这里找到我的function.json
内容:
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "res",
"type": "http",
"direction": "out"
}
]
}
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");
}
}
}
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");
}
}
}
答案 0 :(得分:2)
简短答案
生成过程将根据为方法附加的属性,为.cs文件中定义的功能生成function.json
文件。例如,Functions文档中有几个示例。 a BlobTrigger function in C#.您不需要添加自己的function.json
。
请参阅“长答案”部分,以详细了解其在后台的工作方式。如果您看到描述了已编译的C#函数的所有预期构建输出,并且函数运行时仍未找到任何函数,请检查您是否在函数应用程序结构的顶级目录上运行func start --build
。 / p>
详细回答
您描述的行为是设计使然。听起来您已经习惯了脚本语言(例如.csx(C#脚本)文件)所使用的Function的文件夹结构。这是一个定义两个函数MyFunction
和MySecondFunction
的示例:
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#称为编译的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 {1}} HttpTrigger`),以确定哪些功能已被定义并创建原始文件夹结构作为其生成输出。
启动Azure Functions运行时(例如,由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.
启动)时,它不会查看func host start
来确定存在哪些函数并绑定绑定。它看起来是FunctionApp
。
在每个功能的文件夹中找到唯一的区别。在已编译的C#函数应用程序中,每个函数的文件夹在C#脚本函数应用程序中都没有.csx文件。仔细查看已编译的C#函数应用程序的FunctionApp/bin/Debug/net461/MyFunction
文件夹中的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"
}
相比,已编译的C#函数的function.json
具有一些额外的字段。这是每个函数运行时的指示:
function.json
:此generatedBy
是在编译期间生成的,不是手工编写的function.json
:此configurationSource
是从C#属性生成的function.json
:包含与此函数相对应的已编译代码的DLL的位置,相对于此scriptFile
文件的位置function.json
:已编译DLL中函数的方法签名长话短说,已编译的C#函数应用程序在运行时依赖于与C#脚本函数应用程序相同的文件夹结构,但是它是由构建过程生成的,而不是由开发人员构建的。用已编译的C#编写功能应用程序的开发人员通过C#属性定义其绑定,而将entryPoint
的生成留给构建过程。