源
- FromRoute 路由值
- FromQuery url查询参数
- FromHeader 请求标头
- FromForm
- FromBody
- FromService 依赖注入提供的服务
- custom 自定义
app.MapGet("/{id}", (int id, int page, [FromHeader(Name = "X-CUSTOM-HEADER")] string customHeader, IOrderService service) => {});
- id 采用路由值绑定
- page 采用查询参数绑定
- customHeader 请求标头绑定
- service 依赖注入
部分参数使用隐式绑定源,id、page customHeader、service。
AsParameters
这个可以理解为结构,当方法的参数绑定过多,或者参数可以复用如分页查询参数,可以使用class 、record 或 struct 包装。
public record OrderPageQueryParams(int page, int take, IOrderServcie service);
app.MapGet("orders", [AsParameters](OrderPageQueryParams queryParams) => {});
官方文档:将 struct 和 AsParameters 一起使用可能比使用 record 类型性能更佳
自定义绑定 官方文档
TryParse
TryParse 具有以下 API :
public static bool TryParse(string value, out T result);
public static bool TryParse(string value, IFormatProvider provider, out T result);
下面的代码显示带有 URI /map?Point=121.23,31.23 的 Point=121.23,31.23
app.MapGet("/map", (Point point) => $"Point: {point.X}, {point.Y}");
public class Point
{
public double X { get; set;}
public double Y { get; set;}
public static bool TryParse(string? value, IFormatProvider? provider, out Point point)
{
var trimmedValue = value?.TrimStart('(').TrimEnd(')');
var segments = trimmedValue?.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (segments?.Length == 2 && double.TryParse(segments[0], out var x) && double.TryParse(segments[1], out var y))
{
point = new Point { X = x, Y = y };
return true;
}
point = null;
return false;
}
}
BindAsync
BindAsync 具有以下 API :
public static ValueTask<T?> BindAsync(HttpContext context, ParameterInfo parameter);
public static ValueTask<T?> BindAsync(HttpContext context);
下面的代码显示带有 URI /products?SortBy=xyz&SortDir=Desc&Page=99 的 SortBy:xyz, SortDirection:Desc, CurrentPage:99:
app.MapGet("/products", (PagingData pageData) => $"SortBy:{pageData.SortBy}, " + $"SortDirection:{pageData.SortDirection}, CurrentPage:{pageData.CurrentPage}");
public class PagingData
{
public string? SortBy { get; init; }
public SortDirection SortDirection { get; init; }
public int CurrentPage { get; init; } = 1;
public static ValueTask<PagingData?> BindAsync(HttpContext context, ParameterInfo parameter)
{
const string sortByKey = "sortBy";
const string sortDirectionKey = "sortDir";
const string currentPageKey = "page";
Enum.TryParse<SortDirection(context.Request.Query[sortDirectionKey], ignoreCase: true, out var sortDirection);
int.TryParse(context.Request.Query[currentPageKey], out var page);
page = page == 0 ? 1 : page;
var result = new PagingData {
SortBy = context.Request.Query[sortByKey],
SortDirection = sortDirection,
CurrentPage = page };
return ValueTask.FromResult<PagingData?>(result);
}
}
public enum SortDirection
{
Default,
Asc,
Desc
}
绑定优先级
- 绑定源规则
- FromRoute
- FormQuery
- FromHeader
- FromBody
- FromForm
- FromServices
- AsParameters
- 特殊类型
- 参数类型具有有效的静态BindAsync方法
- 参数类型为字符串或具有有效的静态 TryParse 方法
- 如果参数类型为依赖项注入提供的服务,则它将该服务用作源
- 参数来自正文