我在这里有我的最小API设置与ASP.NET核心版本和卡特。PutMethod
,PostMethod
,和PatchMethod
工作正常,但我的GetMethod
和DeleteMethod
不返回字符串。
这是我的API版本和最小API:
public class ApiVersions
{
public const string vset = "API_Version_Set";
public static ApiVersion v1 = new ApiVersion(1);
public static ApiVersion v2 = new ApiVersion(2);
public static ApiVersion v3 = new ApiVersion(3);
}
个字符
这是我在Program.cs上的配置:
builder.Services.AddCarter()
.AddEndpointsApiExplorer()
.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.DefaultApiVersion = ApiVersions.v1;
options.AssumeDefaultVersionWhenUnspecified = true;
options.ApiVersionReader = new UrlSegmentApiVersionReader();
}).AddApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
app.MapCarter().NewApiVersionSet(ApiVersions.vset)
.HasApiVersion(ApiVersions.v1)
.HasApiVersion(ApiVersions.v2)
.HasApiVersion(ApiVersions.v3)
.ReportApiVersions()
.Build();
型GetMethod
和DeleteMethod
只有在我在代码中配置一些行时才能正常工作:
方法1:如果我更改了GetMethod
和DeleteMethod
版本:
group.MapGet("{url}", GetMethod).HasApiVersion(ApiVersions.v2);
group.MapGet("{url}", DeleteMethod).HasApiVersion(ApiVersions.v2);
型
方法2:如果我使用[FromRoute]
并删除PutMethod
、PostMethod
和PatchMethod
中的LoginDTO
参数:
public static string GetMethod([FromRoute] string url) => "This is from GET";
public static string DeleteMethod([FromRoute] string url) => "this is from DELETE.";
public static string PutMethod([FromRoute] string url) => "this is from PUT";
public static string PostMethod([FromRoute] string url) => "this is from POST.";
public static string PatchMethod([FromRoute] string url) => "this is from PATCH.";
型
方法3:如果我改变路径:
group.MapPut("put/{url}", PutMethod).HasApiVersion(ApiVersions.v1);
group.MapPost("post/{url}", PostMethod).HasApiVersion(ApiVersions.v1);
group.MapPatch("patch/{url}", PatchMethod).HasApiVersion(ApiVersions.v1);
型
方法4:如果我评论这三个:
//group.MapPut("{url}", PutMethod).HasApiVersion(ApiVersions.v1);
//group.MapPost("{url}", PostMethod).HasApiVersion(ApiVersions.v1);
//group.MapPatch("{url}", PatchMethod).HasApiVersion(ApiVersions.v1);
型
1条答案
按热度按时间w8f9ii691#
我 * 认为 * 我能够重现你的场景。根据你的描述,看起来事情正在 * 工作 *,但它们没有显示在Swagger UI中。你没有分享你的配置的那一部分,但我猜它是不正确的。你没有指定或指出你正在使用哪个OpenAPI生成器,但我假设它是Swashbuckle。有很多事情正在发生,让我们一个一个来解决。
问题1 -路由参数未定义
您定义了路由模板:
字符串
但方法:
型
not有
url
参数。这将导致文本{url}
成为路由路径的一部分。Issue 2 - OpenAPI单据生成
Swashbuckle将急切地评估
AddSwaggerGen
中的设置,因此我们需要使用 Options 通过DI进行不同的解析。我们希望使用从API Versioning中解析IApiVersionDescriptorProvider
,这将整理应用程序中的所有API版本。这将使您能够配置OpenAPI文档,而无需硬编码任何内容。世界上最简单的实现如下所示:型
Issue 3 - API版本元数据
您仍然可以显式地使用旧的
ApiVersionSet
API,但是在端点和/或其组上隐式地配置API版本可能更自然。在引擎盖下总是有一个ApiVersionSet
。与ApiVersionSet
关联的名称是API的逻辑名称,默认情况下将在您集成OpenAPI的API Explorer扩展时使用。API版本元数据必须从根组上滚。当您使用组和端点扩展方法时,将严格执行该行为。当您手动构建
ApiVersionSet
时,只能松散地执行规则,并且出现错误的可能性更大。您可能希望使用两种方法进行配置。还有其他选项,但你可能会对这些感兴趣选项1 -带嵌套组的通用路由模板
此方法在根目录为所有API版本配置路由模板。每组端点必须汇总到一个组以进行正确的排序,因此我们需要添加一个新组(不带路由模板)来表示端点集合。通过在组上应用API版本,该组中的所有端点都将具有父组定义的API版本。
型
选项2 -使用重复路由模板的组
在此方法中,每个组中的路由模板会针对每个API版本进行复制。这可能对您有用,也可能不适用。不同的API版本可能使用不同的路由模板。同样,将API版本添加到组中会隐式地将API版本应用于该组中的所有端点。
型
问题4 - OpenAPI扩展冲突
Microsoft OpenAPI扩展与API Versioning API Explorer扩展不兼容。具体来说,当您使用
WithOpenApi()
时,它会将OpenApiOperation
直接添加到端点作为元数据。这是设计中的一个缺陷。端点可能会使用不同的OpenAPI选项来服务多个API版本。不幸的是,OpenAPI生成器,如Swashbuckle,在元数据中查找OpenApiOoperation
的存在。当存在时,它使用该示例并跳过API Explorer提供的所有其他内容。这可能会导致您不想要的结果。如果您使用的是API版本控制,我建议您不要使用
WithOpenApi()
。您可以使用其他影响OpenAPI的扩展,例如WithSummary
,WithDescription
,Accepts
,Produces
,大多数元数据扩展方法只添加元数据,您不需要使用OpenApiOperation
,使用WithTags
,因为使用ApiVersionSet
配置的名称是默认使用的名称。不需要定义两次,但如果你想,你可以。问题5 -应用配置
您的应用程序配置不需要重新应用
ApiVersionSet
。它已经通过Carter的端点配置应用。将所有部分放在一起,您的应用程序配置应该如下所示:型
这里的一个关键问题是如何调用
UseSwaggerUI
。这个设置需要与ConfigureSwaggerOptions
类中定义的OpenAPI文档的创建方式相关联。双方需要匹配。最后,您可能已经注意到我删除了
UseDefaultVersionWhenUnspecified
。这几乎肯定不会像您认为的那样;至少,不是如图所示。此功能仅用于向后兼容现有API,但经常被滥用。您正在通过URL段进行版本控制,所以该选项无效。模板中间不能有可选路由参数。order/{id}/items
也是如此。该选项将仅如果你也有不包含apiVersion
路由约束的路由(例如:api/general/{url}
),我不建议你在向后兼容性之外做任何事情。