System.Text.Json 在运行时添加 JsonIgnore 属性
System.Text.Json add JsonIgnore attribute at runtime
我正在寻找使用 System.Text.Json
序列化对象的方法,但是根据其他 属性 值忽略了一些 属性。
例如:
public class Data
{
public string Type { get; set; }
public string A { get; set; }
public string B { get; set; }
public string BC { get; set; }
}
我用这些数据填充class
var data = new Data
{
Type = "A",
A = "data A",
B = "data B",
BC = "data BC"
};
当Type
值为A
时,我想序列化属性Type
和A
.
当Type
值为B
时,我想序列化属性Type
、B
和BC
。
等等。
有办法吗?
我曾经用自定义属性制作过 Xml 版本,但是在搜索 System.Text.Json
解决方案时,没有找到。
这是我的 Xml 版本:
public static bool HasAttribute<TAttribute>(
this PropertyInfo prop)
where TAttribute : Attribute
{
return prop.GetCustomAttributes(typeof(TAttribute), false).Any();
}
public static TValue GetAttributeValue<TAttribute, TValue>(
this PropertyInfo prop,
Func<TAttribute, TValue> valueSelector)
where TAttribute : Attribute
{
var att = prop.GetCustomAttributes(typeof(TAttribute), false).FirstOrDefault() as TAttribute;
if (att != null)
{
return valueSelector(att);
}
return default(TValue);
}
private void GenerateAttributeOverrides<T>(string type, XmlAttributeOverrides attributeOverrides, PropertyInfo[] properties)
{
foreach (var prop in properties)
{
var attributes = new XmlAttributes();
if (prop.HasAttribute<ShouldSerializeAttribute>())
{
var acceptedTypes = prop.GetAttributeValue<ShouldSerializeAttribute, string[]>(x => x.AcceptedTypes);
if (acceptedTypes.Contains(type))
{
attributes.XmlElements.Add(new XmlElementAttribute(prop.Name, prop.PropertyType);
}
else
{
attributes.XmlIgnore = true;
}
}
}
提前致谢。
查看自定义转换器后,我已经找到了答案。
这是我的转换器
public class DataConverter : JsonConverter<Data>
{
public override Data Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, Data value, JsonSerializerOptions options)
{
var properties = value.GetType().GetProperties();
writer.WriteStartObject();
foreach (var prop in properties)
{
if (prop.HasAttribute<ShouldSerializeAttribute>())
{
var acceptedTypes = prop.GetAttributeValue<ShouldSerializeAttribute, string[]>(x => x.AcceptedTypes);
if (acceptedTypes != null && acceptedTypes.Contains(value.Type))
{
var propValue = prop.GetValue(value);
writer.WritePropertyName(prop.Name);
JsonSerializer.Serialize(writer, propValue, prop.PropertyType, options);
}
}
}
writer.WriteEndObject();
}
}
我正在寻找使用 System.Text.Json
序列化对象的方法,但是根据其他 属性 值忽略了一些 属性。
例如:
public class Data
{
public string Type { get; set; }
public string A { get; set; }
public string B { get; set; }
public string BC { get; set; }
}
我用这些数据填充class
var data = new Data
{
Type = "A",
A = "data A",
B = "data B",
BC = "data BC"
};
当Type
值为A
时,我想序列化属性Type
和A
.
当Type
值为B
时,我想序列化属性Type
、B
和BC
。
等等。
有办法吗?
我曾经用自定义属性制作过 Xml 版本,但是在搜索 System.Text.Json
解决方案时,没有找到。
这是我的 Xml 版本:
public static bool HasAttribute<TAttribute>(
this PropertyInfo prop)
where TAttribute : Attribute
{
return prop.GetCustomAttributes(typeof(TAttribute), false).Any();
}
public static TValue GetAttributeValue<TAttribute, TValue>(
this PropertyInfo prop,
Func<TAttribute, TValue> valueSelector)
where TAttribute : Attribute
{
var att = prop.GetCustomAttributes(typeof(TAttribute), false).FirstOrDefault() as TAttribute;
if (att != null)
{
return valueSelector(att);
}
return default(TValue);
}
private void GenerateAttributeOverrides<T>(string type, XmlAttributeOverrides attributeOverrides, PropertyInfo[] properties)
{
foreach (var prop in properties)
{
var attributes = new XmlAttributes();
if (prop.HasAttribute<ShouldSerializeAttribute>())
{
var acceptedTypes = prop.GetAttributeValue<ShouldSerializeAttribute, string[]>(x => x.AcceptedTypes);
if (acceptedTypes.Contains(type))
{
attributes.XmlElements.Add(new XmlElementAttribute(prop.Name, prop.PropertyType);
}
else
{
attributes.XmlIgnore = true;
}
}
}
提前致谢。
查看自定义转换器后,我已经找到了答案。
这是我的转换器
public class DataConverter : JsonConverter<Data>
{
public override Data Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, Data value, JsonSerializerOptions options)
{
var properties = value.GetType().GetProperties();
writer.WriteStartObject();
foreach (var prop in properties)
{
if (prop.HasAttribute<ShouldSerializeAttribute>())
{
var acceptedTypes = prop.GetAttributeValue<ShouldSerializeAttribute, string[]>(x => x.AcceptedTypes);
if (acceptedTypes != null && acceptedTypes.Contains(value.Type))
{
var propValue = prop.GetValue(value);
writer.WritePropertyName(prop.Name);
JsonSerializer.Serialize(writer, propValue, prop.PropertyType, options);
}
}
}
writer.WriteEndObject();
}
}