You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制序列化带[JsonIgnore]属性的字段?仅反序列化时忽略

当然可以实现这种序列化可见、反序列化忽略的只读Json属性!下面针对两种主流的.NET Json序列化库,给你具体的实现方案:

使用 Newtonsoft.Json(Json.NET)的方案

如果你用的是老牌的Newtonsoft.Json,有两种常用方式:

方式1:私有Setter + [JsonProperty]标记

如果你的业务场景允许把x的setter设为私有,这是最简单的方案:

public class Cake {
    // 序列化时会读取getter,反序列化时因setter私有无法赋值
    [JsonProperty]
    public int x { get; private set; }
}

这样Json.NET会正常序列化x的值,但反序列化时会自动忽略传入的x字段,完全不会修改属性值。

方式2:自定义ContractResolver(保留公有Setter)

如果必须保留x的公有setter,可以通过自定义ContractResolver来精准控制序列化/反序列化行为:

public class ReadOnlyJsonPropertyResolver : DefaultContractResolver {
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
        var property = base.CreateProperty(member, memberSerialization);
        // 针对名为x的属性,设置为可序列化、不可反序列化
        if (member.Name == nameof(Cake.x)) {
            property.ShouldDeserialize = _ => false;
            property.ShouldSerialize = _ => true;
        }
        return property;
    }
}

使用时在序列化配置里指定这个Resolver:

var settings = new JsonSerializerSettings {
    ContractResolver = new ReadOnlyJsonPropertyResolver()
};
// 序列化
var json = JsonConvert.SerializeObject(cake, settings);
// 反序列化
var deserializedCake = JsonConvert.DeserializeObject<Cake>(json, settings);
使用 System.Text.Json 的方案

如果你用的是.NET Core/.NET 5+自带的System.Text.Json,同样有两种方案:

方式1:私有Setter(无需额外标记)

System.Text.Json默认会序列化带有公有getter的属性,不管setter是否私有;而反序列化时只会处理公有setter。所以直接把setter设为私有即可:

public class Cake {
    // 序列化输出x,反序列化忽略传入的x
    public int x { get; private set; }
}

如果需要在类内部修改x的值,私有setter完全够用。

方式2:自定义TypeInfoResolver(保留公有Setter)

如果必须保留公有setter,可以通过自定义DefaultJsonTypeInfoResolver来控制:

public class ReadOnlyJsonTypeInfoResolver : DefaultJsonTypeInfoResolver {
    public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options) {
        var typeInfo = base.GetTypeInfo(type, options);
        if (type == typeof(Cake)) {
            var property = typeInfo.Properties.FirstOrDefault(p => p.Name == nameof(Cake.x));
            if (property != null) {
                // 禁用反序列化
                property.IsReadOnly = true;
            }
        }
        return typeInfo;
    }
}

使用时配置到JsonSerializerOptions中:

var options = new JsonSerializerOptions {
    TypeInfoResolver = new ReadOnlyJsonTypeInfoResolver()
};
// 序列化
var json = JsonSerializer.Serialize(cake, options);
// 反序列化
var deserializedCake = JsonSerializer.Deserialize<Cake>(json, options);

另外,如果你想通过自定义特性来实现类似[ReadOnlyJsonIgnore]的效果(更优雅的标记),也可以基于上面的Resolver/ContractResolver扩展,扫描自定义特性来批量处理属性,这样就不用硬编码属性名了。

内容的提问来源于stack exchange,提问作者Konrad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:04:04