System.Text.Json中JsonPropertyName在查询参数中被忽略的问题及解决方法
问题解析与解决方案
JsonPropertyName特性是System.Text.Json专门用于JSON序列化/反序列化的标记,和HTTP查询参数的模型绑定逻辑完全不相关,所以你添加该特性后查询参数绑定不生效是正常的。
要实现查询参数site绑定到SiteName属性,有两种可行方案:
方案1:使用ASP.NET Core原生的[FromQuery]特性(推荐)
直接给属性添加[FromQuery(Name = "site")]特性,这是官方专门为查询参数绑定设计的标记,简单直接:
public class SearchQuery { [FromQuery(Name = "site")] public string SiteName { get; set; } }
这样访问https://example.com/search?site=sandbox时,query.SiteName就能正确获取到"sandbox"。
方案2:自定义模型绑定器复用JsonPropertyName配置
如果你的场景需要统一复用JsonPropertyName的命名配置,不想额外添加FromQuery特性,可以自定义一个模型绑定器,读取属性上的JsonPropertyName值来匹配查询参数:
1. 实现自定义模型绑定器
public class JsonPropertyQueryBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext)); var modelInstance = Activator.CreateInstance(bindingContext.ModelType); foreach (var property in bindingContext.ModelType.GetProperties()) { // 读取JsonPropertyName特性的值,没有则用属性本身名称 var jsonAttr = property.GetCustomAttribute<JsonPropertyNameAttribute>(); var queryParamName = jsonAttr?.Name ?? property.Name; // 从查询参数中获取对应值 var valueResult = bindingContext.ValueProvider.GetValue(queryParamName); if (valueResult != ValueProviderResult.None) { property.SetValue(modelInstance, valueResult.FirstValue); } } bindingContext.Result = ModelBindingResult.Success(modelInstance); return Task.CompletedTask; } }
2. 给查询类绑定自定义模型绑定器
[ModelBinder(BinderType = typeof(JsonPropertyQueryBinder))] public class SearchQuery { [JsonPropertyName("site")] public string SiteName { get; set; } }
这样就能让JsonPropertyName特性同时作用于JSON序列化和查询参数绑定了。
内容的提问来源于stack exchange,提问作者Ank
相关产品推荐
相关产品推荐

