最小API項目的助手庫集合。
為最小API項目提供路由助手的庫,用於使用反射自動端點註冊。
該庫可在Nuget上找到。只需在包裝管理器中搜索MinimalHelpers.Routing或在.NET CLI中運行以下命令:
dotnet add package MinimalHelpers.Routing創建一個類來保存您的路由處理程序註冊並使IT實現IEndpointRouteHandlerBuilder接口:
public class PeopleEndpoints : MinimalHelpers . Routing . IEndpointRouteHandlerBuilder
{
public static void MapEndpoints ( IEndpointRouteBuilder endpoints )
{
endpoints . MapGet ( "/api/people" , GetList ) ;
endpoints . MapGet ( "/api/people/{id:guid}" , Get ) ;
endpoints . MapPost ( "/api/people" , Insert ) ;
endpoints . MapPut ( "/api/people/{id:guid}" , Update ) ;
endpoints . MapDelete ( "/api/people/{id:guid}" , Delete ) ;
}
// ...
}在program.cs內部的webapplication對像上調用MapEndpoints()擴展方法在Run()方法調用之前:
// using MinimalHelpers.Routing;
app . MapEndpoints ( ) ;
app . Run ( ) ;默認情況下, MapEndpoints()將掃描調用彙編以搜索實現IEndpointRouteHandlerBuilder接口的類。如果您的路線處理程序在另一個組件中定義,則有兩種選擇:
MapEndpoints()超載MapEndpointsFromAssemblyContaining<T>()擴展方法並指定要掃描的組件中包含的類型您還可以明確地確定要實際映射的類型(在實現IRouteEndpointHandlerBuilder界面的類型中),將謂詞傳遞給MapEndpoints方法:
app . MapEndpoints ( type =>
{
if ( type . Name . StartsWith ( "Products" ) )
{
return false ;
}
return true ;
} ) ;請注意,這些方法依靠反射來掃描組件並找到實現
IEndpointRouteHandlerBuilder接口的類。這可能會產生性能影響,尤其是在大型項目中。如果您有績效問題,請考慮使用明確的註冊方法。此外,該解決方案與天然AOT不兼容。
在最小API項目中為自動端點註冊提供源生成器的庫。
該庫可在Nuget上找到。只需在包裝管理器中搜索MinimalHelpers.Routing或在.NET CLI中運行以下命令:
dotnet add package MinimalHelpers.Routing.Analyzers創建一個類來保存您的路由處理程序註冊並使IT實現IEndpointRouteHandlerBuilder接口:
public class PeopleEndpoints : IEndpointRouteHandlerBuilder
{
public static void MapEndpoints ( IEndpointRouteBuilder endpoints )
{
endpoints . MapGet ( "/api/people" , GetList ) ;
endpoints . MapGet ( "/api/people/{id:guid}" , Get ) ;
endpoints . MapPost ( "/api/people" , Insert ) ;
endpoints . MapPut ( "/api/people/{id:guid}" , Update ) ;
endpoints . MapDelete ( "/api/people/{id:guid}" , Delete ) ;
}
// ...
}請注意,您只需要使用MinimalHelpers.Routing.Analyzers套件。使用此源生成器,
IEndpointRouteHandlerBuilder接口是自動生成的。
在program.cs內部的webapplication對像上調用MapEndpoints()擴展方法在Run()方法調用之前:
app . MapEndpoints ( ) ;
app . Run ( ) ;注意
MapEndpoints方法是由源生成器生成的。
為最小API項目提供OpenAPI幫助者的圖書館。
該庫可在Nuget上找到。只需在包裝管理器GUI中搜索minimalhelpers.openapi或在.NET CLI中運行以下命令:
dotnet add package MinimalHelpers.OpenApiOpenAPI的擴展方法
該庫提供了一些擴展方法,可以簡化最小API項目中的OpenAPI配置。例如,可以使用其狀態代碼自定義響應的描述:
endpoints . MapPost ( "login" , LoginAsync )
. AllowAnonymous ( )
. WithValidation < LoginRequest > ( )
. Produces < LoginResponse > ( StatusCodes . Status200OK )
. Produces < LoginResponse > ( StatusCodes . Status206PartialContent )
. Produces ( StatusCodes . Status403Forbidden )
. ProducesValidationProblem ( )
. WithOpenApi ( operation =>
{
operation . Summary = "Performs the login of a user" ;
operation . Response ( StatusCodes . Status200OK ) . Description = "Login successful" ;
operation . Response ( StatusCodes . Status206PartialContent ) . Description = "The user is logged in, but the password has expired and must be changed" ;
operation . Response ( StatusCodes . Status400BadRequest ) . Description = "Incorrect username and/or password" ;
operation . Response ( StatusCodes . Status403Forbidden ) . Description = "The user was blocked due to too many failed logins" ;
return operation ;
} ) ;RouteHandlerBuilder的擴展方法
通常,我們有多個4xx返回值的端點,每個端點都會產生ProblemDetails響應:
endpoints . MapGet ( "/api/people/{id:guid}" , Get )
. ProducesProblem ( StatusCodes . Status400BadRequest )
. ProducesProblem ( StatusCodes . Status401Unauthorized )
. ProducesProblem ( StatusCodes . Status403Forbidden )
. ProducesProblem ( StatusCodes . Status404NotFound ) ;為了避免多次呼叫ProducesProblem ,我們可以使用庫提供的ProducesDefaultProblem擴展方法:
endpoints . MapGet ( "/api/people/{id:guid}" , Get )
. ProducesDefaultProblem ( StatusCodes . Status400BadRequest , StatusCodes . Status401Unauthorized ,
StatusCodes . Status403Forbidden , StatusCodes . Status404NotFound ) ; 一個為最小API項目提供端點過濾器的庫,該項目使用Mignivalation庫使用數據註釋執行驗證。
該庫可在Nuget上找到。只需搜索最小值。
dotnet add package MinimalHelpers.Validation裝飾具有定義驗證規則的屬性的課程:
using System . ComponentModel . DataAnnotations ;
public class Person
{
[ Required ]
[ MaxLength ( 20 ) ]
public string ? FirstName { get ; set ; }
[ Required ]
[ MaxLength ( 20 ) ]
public string ? LastName { get ; set ; }
[ MaxLength ( 50 ) ]
public string ? City { get ; set ; }
}添加WithValidation<T>()擴展方法以啟用驗證過濾器:
using MinimalHelpers . Validation ;
app . MapPost ( "/api/people" , ( Person person ) =>
{
// ...
} )
. WithValidation < Person > ( ) ;如果驗證失敗,則響應將是一個400 Bad Request ,其中包含驗證錯誤的ValidationProblemDetails問題對象,例如:
{
"type" : " https://tools.ietf.org/html/rfc9110#section-15.5.1 " ,
"title" : " One or more validation errors occurred " ,
"status" : 400 ,
"instance" : " /api/people " ,
"traceId" : " 00-009c0162ba678cae2ee391815dbbb59d-0a3a5b0c16d053e6-00 " ,
"errors" : {
"FirstName" : [
" The field FirstName must be a string or array type with a maximum length of '20'. "
],
"LastName" : [
" The LastName field is required. "
]
}
}如果要自定義驗證,則可以使用ConfigureValidation擴展方法:
using MinimalHelpers . Validation ;
builder . Services . ConfigureValidation ( options =>
{
// If you want to get errors as a list instead of a dictionary.
options . ErrorResponseFormat = ErrorResponseFormat . List ;
// The default is "One or more validation errors occurred"
options . ValidationErrorTitleMessageFactory =
( context , errors ) => $ "There was { errors . Values . Sum ( v => v . Length ) } error(s)" ;
} ) ;例如,如果要使用RESX文件本地化響應的title屬性,則可以使用ValidationErrorTitleMessageFactory 。
為最小API項目提供端點過濾器的庫,以使用FulentValidation執行驗證。
該庫可在Nuget上找到。只需在包裝管理器GUI中搜索MinimalHelpers.FluentValidation或在.NET CLI中運行以下命令:
dotnet add package MinimalHelpers.FluentValidation創建一個擴展AbstractValidator並定義驗證規則的類:
using FluentValidation ;
public record class Product ( string Name , string Description , double UnitPrice ) ;
public class ProductValidator : AbstractValidator < Product >
{
public ProductValidator ( )
{
RuleFor ( p => p . Name ) . NotEmpty ( ) . MaximumLength ( 50 ) . EmailAddress ( ) ;
RuleFor ( p => p . Description ) . MaximumLength ( 500 ) ;
RuleFor ( p => p . UnitPrice ) . GreaterThan ( 0 ) ;
}
}在服務集合中註冊驗證器:
using FluentValidation ;
// Assuming the validators are in the same assembly as the Program class
builder . Services . AddValidatorsFromAssemblyContaining < Program > ( ) ;添加WithValidation<T>()擴展方法以啟用驗證過濾器:
using MinimalHelpers . FluentValidation ;
app . MapPost ( "/api/products" , ( Product product ) =>
{
// ...
} )
. WithValidation < Product > ( ) ;如果驗證失敗,則響應將是一個400 Bad Request ,其中包含驗證錯誤的ValidationProblemDetails問題對象,例如:
{
"type" : " https://tools.ietf.org/html/rfc9110#section-15.5.1 " ,
"title" : " One or more validation errors occurred " ,
"status" : 400 ,
"instance" : " /api/products " ,
"traceId" : " 00-f4ced0ae470424dd04cbcebe5f232dc5-bbdcc59f310ebfb8-00 " ,
"errors" : {
"Name" : [
" 'Name' cannot be empty. "
],
"UnitPrice" : [
" 'Unit Price' must be grater than '0'. "
]
}
}如果要自定義驗證,則可以使用ConfigureValidation擴展方法:
using MinimalHelpers . Validation ;
builder . Services . ConfigureValidation ( options =>
{
// If you want to get errors as a list instead of a dictionary.
options . ErrorResponseFormat = ErrorResponseFormat . List ;
// The default is "One or more validation errors occurred"
options . ValidationErrorTitleMessageFactory =
( context , errors ) => $ "There was { errors . Values . Sum ( v => v . Length ) } error(s)" ;
} ) ;例如,如果要使用RESX文件本地化響應的title屬性,則可以使用ValidationErrorTitleMessageFactory 。
貢獻
該項目不斷發展。歡迎捐款。隨時提出問題並提取回購請求,我們將盡可能地解決。