.NET 6中如何在每次请求时动态更新AddJsonOptions?
.NET 6中按请求动态配置Newtonsoft.Json的ContractResolver
你的核心问题是启动时配置的AddNewtonsoftJson只会执行一次,无法在每次请求时根据传入的requestOption实例化带参数的CustomContractResolver。解决方案是通过自定义Json输出格式化器,在每次请求序列化时动态创建CustomContractResolver:
步骤1:注册HttpContext访问器
首先将IHttpContextAccessor注入到DI容器,用于在请求过程中获取当前上下文:
builder.Services.AddHttpContextAccessor();
步骤2:替换默认的NewtonsoftJson输出格式化器
在Mvc配置中移除默认格式化器,添加自定义的实现,确保每次请求都能动态生成序列化配置:
builder.Services.AddMvc() .AddNewtonsoftJson(options => { // 移除默认的NewtonsoftJson输出格式化器 options.OutputFormatters.RemoveType<NewtonsoftJsonOutputFormatter>(); // 获取DI容器中的IHttpContextAccessor实例 var httpContextAccessor = builder.Services.BuildServiceProvider().GetRequiredService<IHttpContextAccessor>(); // 添加自定义格式化器 options.OutputFormatters.Add(new CustomJsonOutputFormatter(options.SerializerSettings, httpContextAccessor)); });
步骤3:实现自定义Json输出格式化器
继承NewtonsoftJsonOutputFormatter,重写CreateJsonSerializer方法,每次序列化时从当前请求中获取参数并创建CustomContractResolver:
public class CustomJsonOutputFormatter : NewtonsoftJsonOutputFormatter { private readonly IHttpContextAccessor _httpContextAccessor; public CustomJsonOutputFormatter(JsonSerializerSettings serializerSettings, IHttpContextAccessor httpContextAccessor) : base(serializerSettings, httpContextAccessor.HttpContext?.RequestServices.GetRequiredService<ArrayPool<char>>()) { _httpContextAccessor = httpContextAccessor; } protected override JsonSerializer CreateJsonSerializer() { var serializer = base.CreateJsonSerializer(); // 从当前请求中获取参数(示例从QueryString获取,可替换为Header/路由参数等) var requestOption = _httpContextAccessor.HttpContext?.Request.Query["requestOption"].FirstOrDefault(); // 动态实例化带参数的CustomContractResolver serializer.ContractResolver = new CustomContractResolver(requestOption); return serializer; } }
关键说明
CreateJsonSerializer方法会在每次请求序列化响应时被调用,因此能保证每次都基于当前请求的参数创建CustomContractResolver。- 如果需要从请求Body中获取参数,需要先启用请求Body的可重读功能(比如在中间件中调用
context.Request.EnableBuffering()),避免格式化器读取时Body已被消耗。
内容的提问来源于stack exchange,提问作者Vicent
相关产品推荐
相关产品推荐

