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

.NET 7 Web API如何根据请求动态配置JsonSerializerOptions

动态控制.NET 7 Web API JSON序列化行为

问题背景

我有一个返回User对象的.NET 7 Web API接口,User类定义如下:

public class User
{
    public Guid? Id { get; set; }
    public String? Name { get; set; }
    public Int32? Age { get; set; }
    public String? HairColor { get; set; }
}

当请求携带Select查询参数(例如值为Name)时,数据库仅返回Name属性,但接口通过Ok(users)返回的JSON会包含所有null或默认值的属性。为节省响应包体积,希望此时仅返回非默认值的属性;若请求未携带Select查询参数,则返回所有属性(即使为null或默认值)。

需要动态设置JsonSerializerOptions:

JsonSerializerOptions options = new()
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};

使得存在Select参数时序列化忽略null/default属性,否则返回所有属性。

解决方案

方法一:单个Action内直接控制序列化选项

在API的Action方法中,先获取Select查询参数,根据参数是否存在选择对应的序列化配置,返回自定义JsonResult:

[HttpGet]
public IActionResult GetUsers([FromQuery] string? select)
{
    // 模拟数据库查询:根据select参数返回仅包含指定属性的User集合
    var users = FetchUsersFromDatabase(select);

    var serializerOptions = string.IsNullOrEmpty(select)
        ? new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.Never }
        : new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault };

    return new JsonResult(users, serializerOptions);
}

这种方式简单直接,适合仅单个Action需要该逻辑的场景。

方法二:全局ActionFilter统一控制

如果多个Action都需要此逻辑,可以自定义过滤器,在结果执行阶段动态修改序列化配置:

public class DynamicJsonFilter : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is ObjectResult objectResult)
        {
            var selectParam = context.HttpContext.Request.Query["select"].FirstOrDefault();
            JsonSerializerOptions options;

            if (!string.IsNullOrEmpty(selectParam))
            {
                options = new JsonSerializerOptions
                {
                    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
                };
            }
            else
            {
                options = new JsonSerializerOptions
                {
                    DefaultIgnoreCondition = JsonIgnoreCondition.Never
                };
            }

            // 替换ObjectResult的序列化选项
            objectResult.JsonSerializerOptions = options;
        }

        base.OnResultExecuting(context);
    }
}

注册全局过滤器(Program.cs):

builder.Services.AddControllers(options =>
{
    options.Filters.Add<DynamicJsonFilter>();
});

或单独在Action上启用:

[HttpGet]
[DynamicJsonFilter]
public IActionResult GetUsers([FromQuery] string? select)
{
    var users = FetchUsersFromDatabase(select);
    return Ok(users);
}

这种方式可统一管理多个Action的序列化逻辑,减少重复代码。

注意事项

若项目已有全局JsonSerializerOptions配置,可基于全局配置修改,避免重复设置其他属性:

var globalOptions = context.HttpContext.RequestServices.GetRequiredService<IOptions<JsonOptions>>().Value.JsonSerializerOptions;
var options = new JsonSerializerOptions(globalOptions);
options.DefaultIgnoreCondition = string.IsNullOrEmpty(selectParam) 
    ? JsonIgnoreCondition.Never 
    : JsonIgnoreCondition.WhenWritingDefault;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:50:23