我有一个函数定义如下:
public class RegistrationFunction(
IUserExistsQuery userExistsQuery,
IRegisterUserCommand registerUser)
{
[Function(nameof(RegistrationFunction))]
[OpenApiOperation(operationId: "RegisterUser", Visibility = OpenApiVisibilityType.Important)]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "x-functions-key", In = OpenApiSecurityLocationType.Header)]
[OpenApiRequestBody(contentType: MediaTypeNames.Application.Json, bodyType: typeof(UserDataRequestBody))]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.OK)]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.Conflict)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.BadRequest, bodyType: typeof(RegistrationErrorResponseBody), contentType: MediaTypeNames.Application.Json)]
public async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
[FromBody] UserDataRequestBody userData)
{
// code removed for brevity
}
}
我还使用正确的包参考来启用 OpenApi 文档:
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="1.5.1" />
我的 Program.cs 包含此代码,我也认为这是正确的:
var host = new HostBuilder()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterType<UserExistsQuery>().AsImplementedInterfaces().SingleInstance();
builder.RegisterType<RegisterUserCommand>().AsImplementedInterfaces().SingleInstance();
})
.ConfigureServices(services =>
{
services.AddDbContext<MLTRContext>(options =>
{
var connectionString = Environment.GetEnvironmentVariable("PostgresConnectionString");
options.UseNpgsql(connectionString);
});
services.AddSingleton<IOpenApiConfigurationOptions>(_ =>
{
var options = new OpenApiConfigurationOptions
{
Info = new OpenApiInfo
{
Version = DefaultOpenApiConfigurationOptions.GetOpenApiDocVersion(),
Title = $"{DefaultOpenApiConfigurationOptions.GetOpenApiDocTitle()} (Injected)",
Description = DefaultOpenApiConfigurationOptions.GetOpenApiDocDescription(),
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
Contact = new OpenApiContact
{
Name = "Enquiry",
Email = "[email protected]",
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
},
License = new OpenApiLicense
{
Name = "MIT",
Url = new Uri("http://opensource.org/licenses/MIT"),
}
},
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
OpenApiVersion = DefaultOpenApiConfigurationOptions.GetOpenApiVersion(),
IncludeRequestingHostName = DefaultOpenApiConfigurationOptions.IsFunctionsRuntimeEnvironmentDevelopment(),
ForceHttps = DefaultOpenApiConfigurationOptions.IsHttpsForced(),
ForceHttp = DefaultOpenApiConfigurationOptions.IsHttpForced(),
};
return options;
});
})
.ConfigureFunctionsWorkerDefaults(w =>
w
.UseMiddleware<ErrorExposingMiddleware>()
.UseMiddleware<PrintEnvVarsMiddleware>())
.Build();
await host.RunAsync();
但是,当我在本地构建并运行代码时,控制台中没有出现 OpenApi 端点,如果我尝试访问 /api/swagger/ui,我会得到 404。可能是因为我的代码布局有点不-标准?
| - Program.cs
| - local.settings.json
| | - Functions
| | | - Registration
| | | | - RegistrationFunction.cs
或者也许是因为我正在运行
<TargetFramework>net8.0</TargetFramework>
并且此处的所有示例都使用 v7 max:https://github.com/Azure/azure-functions-openapi-extension/blob/main/samples/Microsoft.Azure。 Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc.csproj ?
通过使用下面的代码,我也能够获取 OpenAPI 端点和响应。
我在上述文件中有以下代码。
函数.cs -
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System.Net;
namespace FunctionApp62
{
public class Function1
{
private readonly ILogger<Function1> _logger;
public Function1(ILogger<Function1> logger)
{
_logger = logger;
}
[OpenApiOperation(operationId: "greeting", tags: new[] { "greeting" }, Summary = "Greetings", Description = "This shows a welcome message.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Summary = "The response", Description = "This returns the response")]
[Function("Function1")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult("Welcome to Azure Functions!");
}
}
}
Program.cs -
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
.ConfigureOpenApi()
.Build();
host.Run();
.csproj -
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.OpenApi" Version="2.0.0-preview2" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.3-preview1" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
</ItemGroup>
</Project>
我能够获得如下所示的端点-
Azure Functions Core Tools
Core Tools Version: 4.0.5611 Commit hash: N/A +591b8ae*****fe0655 (64-bit)
Function Runtime Version: 4.31.1.22191
[2024-04-29T06:15:29.663Z] Found C:\Users\******\FunctionApp62\FunctionApp62\FunctionApp62.csproj. Using for user secrets file configuration.
[2024-04-29T06:15:32.569Z] Azure Functions .NET Worker (PID: 12100) initialized in debug mode. Waiting for debugger to attach...
[2024-04-29T06:15:32.620Z] Worker process started and initialized.
Functions:
Function1: [GET,POST] http://localhost:7296/api/Function1
RenderOAuth2Redirect: [GET] http://localhost:7296/api/oauth2-redirect.html
RenderOpenApiDocument: [GET] http://localhost:7296/api/openapi/{version}.{extension}
RenderSwaggerDocument: [GET] http://localhost:7296/api/swagger.{extension}
RenderSwaggerUI: [GET] http://localhost:7296/api/swagger/ui
For detailed output, run func with --verbose flag.
[2024-04-29T06:15:37.684Z] Host lock lease acquired by instance ID '000000000000000000000000BF6D1ED5'.
[2024-04-29T06:16:04.141Z] Executing 'Functions.RenderSwaggerUI' (Reason='This function was programmatically called via the host APIs.', Id=8f370a16-bd07-4fae-b900-2ea3b65dc81f)
[2024-04-29T06:16:04.447Z] SwaggerUI page was requested.
[2024-04-29T06:16:05.120Z] Executed 'Functions.RenderSwaggerUI' (Succeeded, Id=8f370a16-bd07-4fae-b900-2ea3b65dc81f, Duration=996ms)
[2024-04-29T06:16:05.246Z] Executing 'Functions.RenderSwaggerDocument' (Reason='This function was programmatically called via the host APIs.', Id=bfb3de02-493d-496c-bd0e-2b2bcf78fdf3)
[2024-04-29T06:16:05.257Z] swagger.json was requested.
[2024-04-29T06:16:05.931Z] Executed 'Functions.RenderSwaggerDocument' (Succeeded, Id=bfb3de02-493d-496c-bd0e-2b2bcf78fdf3, Duration=686ms)
[2024-04-29T06:17:20.115Z] Executing 'Functions.Function1' (Reason='This function was programmatically called via the host APIs.', Id=14303a95-f684-48a9-9475-1836ad752a5d)
[2024-04-29T06:17:20.140Z] C# HTTP trigger function processed a request.
[2024-04-29T06:17:20.211Z] Executed 'Functions.Function1' (Succeeded, Id=14303a95-f684-48a9-9475-1836ad752a5d, Duration=96ms)