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

如何实现包含/不包含私有属性的JSON序列化?

两种JSON序列化方案(包含/不包含私有属性)

针对你的需求,以下几种方案无需创建重复类,可在运行时灵活控制序列化行为:

方案1:使用Newtonsoft.Json(Json.NET)动态控制序列化成员

Newtonsoft.Json支持通过自定义契约解析器,动态决定哪些属性参与序列化,无需修改原类结构。

包含私有属性的序列化

创建自定义契约解析器,强制包含所有私有属性:

public class IncludePrivatePropertiesResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        // 获取类的所有属性(公有+私有)
        var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                             .Select(p => base.CreateProperty(p, memberSerialization))
                             .ToList();
        // 标记所有属性为可序列化
        foreach (var prop in properties)
        {
            prop.ShouldSerialize = _ => true;
            prop.Writable = true;
            prop.Readable = true;
        }
        return properties;
    }
}

使用示例:

var book = new Book();
// 生成包含私有属性的JSON
var includePrivateSettings = new JsonSerializerSettings
{
    ContractResolver = new IncludePrivatePropertiesResolver()
};
string jsonWithPrivate = JsonConvert.SerializeObject(book, includePrivateSettings);

不包含私有属性的序列化

直接使用默认配置即可,默认只序列化公有属性:

string jsonWithoutPrivate = JsonConvert.SerializeObject(book);

方案2:使用System.Text.Json的自定义JsonTypeInfo

如果坚持使用System.Text.Json,可通过自定义类型信息解析器,动态添加私有属性到序列化列表:

包含私有属性的配置

var includePrivateOptions = new JsonSerializerOptions();
includePrivateOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
    Modifiers =
    {
        typeInfo =>
        {
            if (typeInfo.Type == typeof(Book))
            {
                // 反射获取所有私有属性并添加到序列化配置
                var privateProperties = typeof(Book).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic);
                foreach (var prop in privateProperties)
                {
                    var propertyInfo = typeInfo.CreateJsonPropertyInfo(prop.PropertyType, prop.Name);
                    propertyInfo.Get = obj => prop.GetValue(obj);
                    propertyInfo.Set = (obj, value) => prop.SetValue(obj, value);
                    typeInfo.Properties.Add(propertyInfo);
                }
            }
        }
    }
};

使用示例:

string jsonWithPrivate = JsonSerializer.Serialize(book, includePrivateOptions);

不包含私有属性的配置

直接使用默认JsonSerializerOptions,默认只处理公有属性:

string jsonWithoutPrivate = JsonSerializer.Serialize(book);

方案3:用AutoMapper动态生成映射对象

通过AutoMapper在运行时动态映射到匿名类型或动态对象,避免手动编写重复类:

配置AutoMapper

var config = new MapperConfiguration(cfg =>
{
    // 映射到包含所有属性(包括私有)的动态类型
    cfg.CreateMap<Book, dynamic>().ForAllMembers(opt => opt.MapFrom(src => 
        typeof(Book).GetProperty(opt.DestinationMemberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(src)));
    
    // 映射到只包含公有属性的动态类型(默认行为,可省略)
    cfg.CreateMap<Book, ExpandoObject>();
});
var mapper = config.CreateMapper();

使用示例

// 生成包含私有属性的JSON
var bookWithPrivate = mapper.Map<dynamic>(book);
string jsonWithPrivate = JsonSerializer.Serialize(bookWithPrivate);

// 生成不包含私有属性的JSON
var bookWithoutPrivate = mapper.Map<ExpandoObject>(book);
string jsonWithoutPrivate = JsonSerializer.Serialize(bookWithoutPrivate);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:42:56