C#System.Text.Json或Newtonsoft Json属性按属性标记序列化控制

C#System.Text.Json或Newtonsoft Json属性按属性标记序列化控制,c#,json,serialization,attributes,deserialization,C#,Json,Serialization,Attributes,Deserialization,我只是想知道我是否可以通过任何属性来标记类实例的某些属性,并在序列化过程中仅序列化那些标记的属性(当然,通过反序列化,在类实例中,通过属性也只影响标记的属性,反之亦然-其余属性应保持不变…) 我知道如何通过反射识别这些属性,但我不想自己进行另一个Json序列化 [MyFirstAttribute] public string A { get; set; } = "hi"; [MyFirstAttribute] public int B { get; set; } = 13;

我只是想知道我是否可以通过任何属性来标记类实例的某些属性,并在序列化过程中仅序列化那些标记的属性(当然,通过反序列化,在类实例中,通过属性也只影响标记的属性,反之亦然-其余属性应保持不变…)

我知道如何通过反射识别这些属性,但我不想自己进行另一个Json序列化

[MyFirstAttribute]
public string A { get; set; } = "hi";

[MyFirstAttribute]
public int B { get; set; } = 13;

[MySecondAttribute]
public string C { get; set; } = "something";
正如本文中所述,您可以通过继承
JsonConverter
类来创建自定义
CustomJsonConverter

然后像这样使用它:

Employee employee = new Employee
{
    FirstName = "James",
    LastName = "Newton-King",
    Roles = new List<string>
    {
        "Admin"
    }
};

string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new KeysJsonConverter(typeof(Employee)));

Console.WriteLine(json);
Employee=新员工
{
FirstName=“詹姆斯”,
LastName=“牛顿·金”,
角色=新列表
{
“管理员”
}
};
string json=JsonConvert.SerializeObject(employee,Formatting.Indented,new-KeysJsonConverter(typeof(employee));
Console.WriteLine(json);

基于@ArgeKumandan的建议:

public class KeysJsonConverter : JsonConverter
{
    private readonly Type[] _types;
    public KeysJsonConverter(params Type[] types) => _types = types;

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);
        if (t.Type != JTokenType.Object) t.WriteTo(writer);
        else
        {
            JObject jo = new JObject();
            foreach (PropertyInfo prop in value.GetType().GetProperties())
            {
                if (!prop.CanRead) continue;
                object propVal = prop.GetValue(value, null);
                if (propVal is null || !Attribute.IsDefined(prop, _types[0])) continue;
                    jo.Add(prop.Name, JToken.FromObject(propVal, serializer));
            }
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override bool CanRead { get => false; }

    public override bool CanConvert(Type objectType) => _types.Any(t => t == _types[0]);
}
然后是用法:

// serialization
var json = JsonConvert.SerializeObject(objectInstance1, Formatting.Indented, new KeysJsonConverter(typeof(MyFirstAttribute)));

// deserialization to an existing instance that updates just the properties contained in JSON
JsonConvert.PopulateObject(jsonCommon, objectInstance2);

我想这就是你想要的: