C#中如何忽略基类ViewModelBase的IsInDesignMode属性以避免JSON序列化
解决Json序列化时忽略基类ViewModelBase的IsInDesignMode属性问题
这个问题我之前处理过,你遇到的核心问题是:Json.NET(你用到的JsonProperty和JsonIgnore都是它的特性)会默认序列化整个继承链上的公共属性,你之前尝试的new关键字只是在派生类里隐藏了基类的属性,但基类的IsInDesignMode依然存在于类型的成员列表中,序列化器还是会找到并序列化它,所以JsonIgnore只标记了派生类的同名属性,根本没作用到基类的那个。
下面给你两种靠谱的解决方案:
方案一:使用JsonObject(MemberSerialization.OptIn)标记派生类
这种方法最直接,告诉序列化器只序列化显式标记了[JsonProperty]的成员,基类的所有未标记属性都会被自动忽略:
[JsonObject(MemberSerialization.OptIn)] public class SettingsExpires : ViewModelBase { private int? frequency; [JsonProperty("frequency")] public int? Frequency { get => frequency; set => this.Set(ref frequency, value); } }
这样序列化后只会得到你想要的{"frequency": null},基类的IsInDesignMode完全不会出现在结果里。
方案二:自定义ContractResolver全局忽略特定属性
如果你的项目里有很多继承自ViewModelBase的类,都需要忽略IsInDesignMode,可以写一个自定义的契约解析器,一次性搞定全局的需求:
首先创建自定义Resolver:
public class IgnoreViewModelBasePropertiesResolver : DefaultContractResolver { protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var properties = base.CreateProperties(type, memberSerialization); // 过滤掉ViewModelBase中声明的IsInDesignMode属性 return properties.Where(p => !(p.DeclaringType == typeof(ViewModelBase) && p.PropertyName == "IsInDesignMode") ).ToList(); } }
然后在序列化时指定这个Resolver:
var jsonSettings = new JsonSerializerSettings { ContractResolver = new IgnoreViewModelBasePropertiesResolver() }; var serializedJson = JsonConvert.SerializeObject(yourSettingsExpiresInstance, jsonSettings);
这种方式不需要修改每个派生类的代码,适合批量处理场景。
为什么之前的写法无效?
再补充解释下:你用new声明的派生类属性,只是在编译时隐藏了基类的属性,但在反射层面(序列化器依赖反射遍历成员),基类的IsInDesignMode依然是独立存在的公共成员。你给派生类的同名属性加JsonIgnore,只会让序列化器忽略派生类的这个属性,基类的那个还是会被序列化,所以结果里依然会出现"IsInDesignMode": false。
内容的提问来源于stack exchange,提问作者Янислав Колодочка
相关产品推荐
相关产品推荐

