将FirstModel字段转为SecondModel中Dictionary字段的异常问题排查
问题分析与解决方法
核心问题
你的代码存在两个关键错误,导致字典未正确填充,最终序列化结果不符合预期:
- 混淆字段与属性:
FirstModel中定义的是自动属性(如public int uid { get; set; }),但你用GetFields()方法获取字段——该方法仅返回类的字段(如private int _uid;这类底层字段),不会返回属性,因此firstModelFields是空数组,字典没有任何键值对。 - GetValue参数错误:即使拿到正确的成员,
firstModelField.GetValue(fieldName)的参数应该是对象实例(即firstModel),而非字段名,这会导致运行时异常。
另外,空字典在JSON序列化时(以System.Text.Json为例)会默认生成additionalPropN的占位结构,这就是你看到的错误结果。
DbContext的注册顺序和该问题无关,无需调整。
修正后的代码
方法1:反射获取属性并填充字典
namespace SomeApp.Models { public class SecondModel { // 其他字段 public Dictionary<string, string> FirstModelTransfer { get; set; } = new(); public void SetFirstModelTransfer(FirstModel firstModel) { // 获取所有公共实例属性 PropertyInfo[] firstModelProps = typeof(FirstModel).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in firstModelProps) { // 获取属性值,处理null避免空引用异常 var value = prop.GetValue(firstModel); string stringValue = value?.ToString() ?? string.Empty; // 过滤不需要的属性(如uid、id) if (prop.Name != "uid" && prop.Name != "id") { FirstModelTransfer[prop.Name] = stringValue; } } } } }
方法2:直接序列化对象转字典(更简洁)
利用JSON序列化库直接将FirstModel转为字典,无需手动反射:
using System.Text.Json; namespace SomeApp.Models { public class SecondModel { // 其他字段 public Dictionary<string, string> FirstModelTransfer { get; set; } = new(); public void SetFirstModelTransfer(FirstModel firstModel) { var serializeOptions = new JsonSerializerOptions { IgnoreNullValues = true }; // 先序列化再反序列化为字典 var json = JsonSerializer.Serialize(firstModel, serializeOptions); FirstModelTransfer = JsonSerializer.Deserialize<Dictionary<string, string>>(json); // 移除不需要的属性 FirstModelTransfer.Remove("uid"); FirstModelTransfer.Remove("id"); } } }
验证序列化结果
修正后,序列化SecondModel会得到符合预期的结果:
{ // 其他字段 "FirstModelTransfer": { "firstname": "Sample firstname", "lastname": "Sample lastname" } }
内容的提问来源于stack exchange,提问作者Prosy A.
相关产品推荐
相关产品推荐

