C# 如何将function.json添加到现有的.NET函数2.0
当我使用C# 如何将function.json添加到现有的.NET函数2.0,c#,azure,azure-functions,serverless,C#,Azure,Azure Functions,Serverless,当我使用func new--name MyHttpTrigger--template“HttpTrigger”添加新函数时,此函数中没有创建函数.json,当我尝试将其添加到当前目录并运行func start--build时,我遇到以下错误: 找不到作业函数。试着公开你的作业类和方法。如果您正在使用绑定扩展(例如Azure存储、ServiceBus、计时器等),请确保已在启动代码中调用扩展的注册方法(例如builder.AddAzureStorage()、builder.AddServiceBu
func new--name MyHttpTrigger--template“HttpTrigger”
添加新函数时,此函数中没有创建函数.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
{
公共静态类httpTrigger
{
[函数名(“httpTrigger”)]
公共静态异步任务运行(
[HttpTrigger(AuthorizationLevel.Function,“get”,“post”,Route=null)]HttpRequest请求,
ILogger日志)
{
LogInformation(“C#HTTP触发器函数处理了一个请求。”);
字符串名称=请求查询[“名称”];
string requestBody=等待新的StreamReader(req.Body).ReadToEndAsync();
动态数据=JsonConvert.DeserializeObject(requestBody);
名称=名称??数据?.name;
返回名称!=null
?(ActionResult)新的OkObjectResult($“你好,{name}”)
:new BadRequestObjectResult(“请在查询字符串或请求正文中传递名称”);
}
}
}
新的httpTrigger函数
namespace final
{
公共静态类httpTrigger
{
公共静态异步任务运行(HttpRequest请求,ILogger日志)
{
LogInformation(“C#HTTP触发器函数处理了一个请求。”);
字符串名称=请求查询[“名称”];
string requestBody=等待新的StreamReader(req.Body).ReadToEndAsync();
动态数据=JsonConvert.DeserializeObject(requestBody);
名称=名称??数据?.name;
返回名称!=null
?(ActionResult)新的OkObjectResult($“你好,{name}”)
:new BadRequestObjectResult(“请在查询字符串或请求正文中传递名称”);
}
}
}
简短回答
构建过程负责根据附加到方法的属性为.cs文件中定义的函数生成function.json
文件。函数文档中有几个示例,例如,您不需要添加自己的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#script编写。(|)之后,添加了常规的C#支持。我将参考常规C#as compiled C#,以强调它与C#script之间的区别
与编译的C#函数应用程序相同的示例具有如下文件夹结构:
FunctionApp
| - bin
| - obj
| - host.json
| - local.settings.json
| - FunctionApp.csproj
| - MyFunction.cs
| - MySecondFunction.cs
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
{
"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"
}
如果您构建此项目并展开FunctionApp/bin
文件夹,您将看到如下内容:
FunctionApp
| - bin
| - obj
| - host.json
| - local.settings.json
| - FunctionApp.csproj
| - MyFunction.cs
| - MySecondFunction.cs
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
{
"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"
}
(netstandard2.0
文件夹将包含与net461
文件夹类似的内容;它们只是不同的框架构建目标。)
请注意,编译的C#function应用程序文件夹结构中的FunctionApp/bin/Debug/net461与C#script应用程序文件夹结构中的FunctionApp之间的相似性。这是因为C#(不是C#脚本)函数应用程序的生成过程使用.cs文件(例如
HttpTrigger`)中方法的属性来确定定义了哪些函数,并创建原始文件夹结构作为其生成输出
当Azure Functions运行时启动时(例如通过func host start
),它不会查看FunctionApp
来找出存在哪些函数并连接绑定。它查看functionpp/bin/Debug/net461/MyFunction
唯一的区别是每个函数的文件夹。在已编译的C#function应用程序中,每个函数的文件夹都缺少C#script函数应用程序中的.csx文件。仔细查看编译后的C#function应用程序的functionpp/bin/Debug/net461/MyFunction
文件夹中的function.json
,您会看到如下内容:
FunctionApp
| - bin
| - obj
| - host.json
| - local.settings.json
| - FunctionApp.csproj
| - MyFunction.cs
| - MySecondFunction.cs
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
{
"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#script函数创建的function.json
相比,编译后的C#function的function.json
有几个额外的字段。以下是每个函数对函数运行时的指示:
generatedBy
:此函数.json
是在编译过程中生成的,不是手工编写的
configurationSource
:此函数.json
是从C#属性生成的
scriptFile
:包含与此函数对应的编译代码的DLL的位置,相对于此函数.json
文件的位置
入口点
:编译的DLL中函数的方法签名
长话短说,编译后的C#函数应用程序在运行时依赖于与C#脚本函数应用程序相同的文件夹结构,但它是由构建过程生成的,而不是由开发人员构建的。编写函数的开发人员