C# 使用Reflection序列化类指定嵌套属性并保留层级输出JSON
实现方案
核心思路是按.拆分属性路径后,逐层反射获取属性值,同时构建嵌套的动态对象,最后序列化该动态对象即可得到符合要求的JSON结构。
完整代码实现
using System; using System.Dynamic; using System.Reflection; using Newtonsoft.Json; public static class PropertySerializer { public static string SerializeSpecificProperty(object instance, string propertyPath) { // 入参校验 if (instance == null) throw new ArgumentNullException(nameof(instance)); if (string.IsNullOrWhiteSpace(propertyPath)) throw new ArgumentException("属性路径不能为空", nameof(propertyPath)); var propertySegments = propertyPath.Split('.', StringSplitOptions.RemoveEmptyEntries); if (propertySegments.Length == 0) throw new ArgumentException("属性路径格式无效", nameof(propertyPath)); // 动态构建嵌套层级结构 dynamic rootObject = new ExpandoObject(); var currentDynamicLevel = rootObject; object currentEntityInstance = instance; for (int i = 0; i < propertySegments.Length; i++) { var currentPropName = propertySegments[i]; // 反射获取当前层级的公开实例属性 var propertyInfo = currentEntityInstance.GetType() .GetProperty(currentPropName, BindingFlags.Public | BindingFlags.Instance); if (propertyInfo == null) throw new ArgumentException($"属性路径中不存在指定属性:{currentPropName}", nameof(propertyPath)); var propertyValue = propertyInfo.GetValue(currentEntityInstance); // 最后一级属性直接赋值 if (i == propertySegments.Length - 1) { ((IDictionary<string, object>)currentDynamicLevel)[currentPropName] = propertyValue; } else { // 中间层级为null无法继续遍历,提前抛出异常 if (propertyValue == null) throw new InvalidOperationException($"属性路径中间层级[{currentPropName}]为null,无法继续遍历"); // 创建下一层动态对象,接入当前层级 var nextDynamicLevel = new ExpandoObject(); ((IDictionary<string, object>)currentDynamicLevel)[currentPropName] = nextDynamicLevel; // 游标移动到下一层 currentDynamicLevel = nextDynamicLevel; currentEntityInstance = propertyValue; } } // 序列化输出带缩进的JSON return JsonConvert.SerializeObject(rootObject, Formatting.Indented); } }
使用说明
- 如果你习惯使用
System.Text.Json作为序列化组件,只需要把最后一行序列化代码替换为:
return System.Text.Json.JsonSerializer.Serialize(rootObject, new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
- 方法天然支持任意类的属性路径序列化,不需要提前适配类结构,只要属性是公开的实例属性即可正常工作。
- 内置了入参校验、路径合法性校验、中间层级空值校验,避免运行时异常。
测试你提供的调用示例,输出结果和你期望的格式完全一致。
内容的提问来源于stack exchange,提问作者Hoang Viet
相关产品推荐
相关产品推荐

