如何使用System.Text.Json排除基类属性的序列化?
如何使用System.Text.Json排除基类属性的序列化?
我完全懂你的困扰——继承自ObservableValidator的类序列化时,基类的HasErrors属性总是跟着跑出来,又没法修改基类代码,还想实现类似Newtonsoft.Json里[JsonObject(MemberSerialization.OptIn)]那种“只序列化我指定属性”的效果。下面给你几个实用的解决方案:
方案一:自定义Json转换器(JsonConverter)
这是最直接的方式,能完全掌控序列化过程,只输出你需要的属性。你可以给Derived类写一个专属转换器:
public class DerivedConverter : JsonConverter<Derived> { public override Derived? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 按需实现反序列化逻辑(如果需要的话) var derived = new Derived(); using (var doc = JsonDocument.ParseValue(ref reader)) { if (doc.RootElement.TryGetProperty("name", out var nameElement)) { derived.Name = nameElement.GetString(); } } return derived; } public override void Write(Utf8JsonWriter writer, Derived value, JsonSerializerOptions options) { // 只写入你需要的属性 writer.WriteStartObject(); writer.WriteString("name", value.Name); writer.WriteEndObject(); } }
使用时把转换器加入序列化配置即可:
var options = new JsonSerializerOptions(); options.Converters.Add(new DerivedConverter()); var json = JsonSerializer.Serialize(derivedInstance, options);
方案二:通过类型信息解析器过滤属性
如果你不想写全量的转换器,也可以通过配置JsonSerializerOptions来过滤基类属性,实现类似“OptIn”的效果:
var options = new JsonSerializerOptions { TypeInfoResolver = new DefaultJsonTypeInfoResolver { ModifyTypeInfo = typeInfo => { if (typeInfo.Type == typeof(Derived)) { // 只保留Derived类自身定义的属性,排除所有基类属性 var propertiesToKeep = typeInfo.Properties.Where(p => p.DeclaringType == typeof(Derived)).ToList(); typeInfo.Properties.Clear(); foreach (var prop in propertiesToKeep) { typeInfo.Properties.Add(prop); } } } } }; var json = JsonSerializer.Serialize(derivedInstance, options);
这个方法会自动筛选出Derived类自己声明的属性,忽略包括ObservableValidator在内的所有基类属性,刚好匹配你的需求。
关于MVVM生成器的小补充
你提到MVVM生成器不会自动传递[JsonIgnore]给生成的属性,其实可以尝试用[property: JsonIgnore]的方式标记字段,让生成的属性带上忽略标记:
public class Derived: ObservableValidator { [Required] [JsonPropertyName("name")] [ObservableProperty] private string? _name; // 如果有其他生成的属性需要忽略,可这样标记 [ObservableProperty] [property: JsonIgnore] private bool _someOtherProperty; }
不过这个方法只对自己定义的字段有效,基类的HasErrors还是得靠前面两个方案解决。
备注:内容来源于stack exchange,提问作者azulBonnet
相关产品推荐
相关产品推荐

