You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Minimal APIs中复刻Web API的[FromBody]必填字段校验功能?

在Minimal APIs中复刻Web API的[FromBody]必填字段校验行为

方案一:使用内置数据注解与ModelState校验

传统Web API的自动必填校验依赖ModelState和数据注解,Minimal APIs默认不会自动触发,但可以通过以下步骤快速启用:

1. 给实体类字段添加必填注解

对字符串等引用类型字段添加[BindRequired]注解;值类型(如int)默认视为必填,无需额外注解(若需语义更明确也可添加):

using Microsoft.AspNetCore.Mvc;

public class SomeObject
{
    [BindRequired]
    public string Subject { get; set; }

    [BindRequired]
    public string Body { get; set; }

    public int Priority { get; set; } // 值类型默认必填
}

2. 在端点中启用ModelState校验

可以通过端点过滤器自动完成校验,无需手动编写检查逻辑:

app.MapPost("/doSomething", async ([FromBody] SomeObject request) =>
{
    // 业务逻辑实现
    return Results.Ok();
})
.AddEndpointFilter<ValidateModelStateFilter>(); // 自动校验ModelState,无效时返回400 BadRequest

如果需要自定义错误响应格式,也可以手动检查ModelState:

app.MapPost("/doSomething", async ([FromBody] SomeObject request, HttpContext context) =>
{
    if (!context.ModelState.IsValid)
    {
        return Results.BadRequest(context.ModelState); // 返回包含错误详情的400响应
    }

    // 业务逻辑实现
    return Results.Ok();
});

方案二:编写通用泛型扩展实现自动校验

如果需要跨多个端点复用校验逻辑,可以编写泛型扩展方法,通过反射自动检查所有必填字段:

1. 实现通用校验扩展

using Microsoft.AspNetCore.Mvc;
using System.Reflection;

public static class MinimalApiValidationExtensions
{
    // 泛型MapPost扩展,自动校验必填字段
    public static RouteHandlerBuilder MapPostWithValidation<T>(this WebApplication app, string pattern, Func<T, Task<IResult>> handler)
        where T : class, new()
    {
        return app.MapPost(pattern, async ([FromBody] T request, HttpContext context) =>
        {
            ValidateRequiredFields(request, context.ModelState);

            if (!context.ModelState.IsValid)
            {
                return Results.BadRequest(context.ModelState);
            }

            return await handler(request);
        });
    }

    // 反射校验必填字段的核心逻辑
    private static void ValidateRequiredFields<T>(T model, ModelStateDictionary modelState)
        where T : class
    {
        var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (var prop in properties)
        {
            // 判断字段是否为必填:非可空值类型,或带有[BindRequired]注解
            bool isRequired = !prop.PropertyType.IsNullableValueType() && prop.PropertyType.IsValueType;
            isRequired |= prop.GetCustomAttributes(typeof(BindRequiredAttribute), inherit: true).Any();

            if (isRequired)
            {
                var value = prop.GetValue(model);
                // 检查值是否为空(字符串额外检查空白内容)
                if (value == null || (prop.PropertyType == typeof(string) && string.IsNullOrWhiteSpace((string)value)))
                {
                    modelState.AddModelError(prop.Name, $"字段 {prop.Name} 为必填项。");
                }
            }
        }
    }

    // 辅助方法:判断是否为可空值类型
    private static bool IsNullableValueType(this Type type)
    {
        return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
    }
}

2. 使用泛型扩展创建端点

只需指定实体类型,即可自动启用必填字段校验,无需重复编写校验代码:

app.MapPostWithValidation<SomeObject>("/doSomething", async (request) =>
{
    // 业务逻辑实现
    return Results.Ok();
});

内容的提问来源于stack exchange,提问作者user4779

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 10:05:07