含IEnumerable属性的类序列化时,内部对象属性未遵循命名策略
问题:包含IEnumerable属性的类序列化时,集合内对象属性未遵循命名策略
问题场景
当序列化包含非泛型IEnumerable属性的类时,集合内对象的属性没有应用已配置的驼峰命名策略,但直接序列化该集合时命名规则正常生效。
配置代码
services .AddOptions<MvcNewtonsoftJsonOptions>() .Configure<IHttpContextAccessor>((options, httpContextAccessor) => { options.UseCamelCasing(true); });
类定义
public class MyViewModel { public string Name { get; set; } // 非泛型IEnumerable属性 public IEnumerable Items { get; set; } } public class MyListItem { public string Text { get; set; } public string Value { get; set; } }
接口代码
public async Task<IActionResult> GetItems(TId id) { var vm = new MyViewModel { Name = "MyViewModel", Items = new List<MyListItem> { new MyListItem { Text = "A", Value = "1" } } }; return Json(vm); }
当前序列化结果
{ "name": "MyViewModel", "items": [{ "Text": "A", "Value": "1" }] }
对比:直接序列化集合的结果
var jsonOptions = ViewContext.GetService<IOptions<MvcNewtonsoftJsonOptions>>(); var serializerSettings = jsonOptions.Value.SerializerSettings; var vm = new MyViewModel { Name = "MyViewModel", Items = new List<MyListItem> { new MyListItem { Text = "A", Value = "1" } } }; JsonConvert.SerializeObject(vm.Items, serializerSettings);
结果:
[{ "text": "A", "value": "1" }]
原因分析
核心问题在于MyViewModel中的Items是非泛型IEnumerable:
- Newtonsoft.Json序列化非泛型集合时,无法推断集合内元素的具体类型,会将元素当作
object处理。 - 默认情况下,针对
object类型的序列化不会自动应用配置的命名策略,因为无法提前知晓对象的属性结构。 - 而直接序列化泛型
List<MyListItem>时,框架明确知道元素类型,因此能正确应用驼峰命名规则。
解决方法
方法1:将属性改为泛型IEnumerable<MyListItem>
这是最直接且推荐的方案,修改MyViewModel的属性定义,让框架明确集合元素类型:
public class MyViewModel { public string Name { get; set; } // 替换为泛型版本 public IEnumerable<MyListItem> Items { get; set; } }
方法2:显式配置全局ContractResolver(无法修改属性类型时使用)
如果无法修改Items的类型,可以直接配置SerializerSettings的ContractResolver,确保所有类型(包括object类型的属性)都应用驼峰命名:
services.AddOptions<MvcNewtonsoftJsonOptions>() .Configure<IHttpContextAccessor>((options, httpContextAccessor) => { // 显式设置驼峰命名解析器,替代UseCamelCasing(true) options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); });
验证效果
修改后,序列化结果会符合预期:
{ "name": "MyViewModel", "items": [{ "text": "A", "value": "1" }] }
内容的提问来源于stack exchange,提问作者Failwyn
相关产品推荐
相关产品推荐

