[英]Conditionally serialize a object in a collection using Json.net
There is tons of info about skipping Properties based on conditionals, but I would like to skip the entire object based on conditions within the object's class. 关于基于条件跳过属性的信息很多,但是我想根据对象类中的条件跳过整个对象。 I would like a solution that is contained within the object's class if at all possible.
我想要一个尽可能包含在对象类中的解决方案。 Keep in mind this is a collection of
myObj
that I am serializing. 请记住,这是我正在序列化的
myObj
的集合。
public class myObj
{
bool conditional;
ShouldSerialize()
{
return conditional;
}
}
Or 要么
public class myObj
{
[JsonCondition]
public bool conditional{get;}
}
Or even 甚至
[JsonCondition(typeof(MyConditionChecker))]
public class myObj
{
public bool conditional{get;}
}
class MyConditionChecker: JsonCondition
{
public override bool CanConvert(object sourceObj)
{
return (sourceObj as myObj).conditional;
}
}
What I got from your comments you would be best served creating your own wrapper around Json that applies the filtering. 我从您的评论中得到的信息最好是为您创建围绕Json的应用过滤器的包装。
public interface IConditionalSerializer
{
bool ShouldBeSerialized();
}
public static class FilteredSerializer
{
public static string SerializeConditional<T>(IEnumerable<T> input)
where T : IConiditionalSerializer
{
return JsonConvert.SerializeObject(input.Where(e => e.ShouldBeSerialized()));
}
}
public class Demo : IConditionalSerializer
{
public bool ShouldBeSerialized() => false;
}
You might also replace the interface with a reflection approach, but keep in mind the performance loss. 您也可以用反射方法替换该接口,但是要记住性能损失。
public interface IConiditionChecker
{
bool ShouldBeSerialized(object instance);
}
public class ConditionAttribute : Attribute
{
public Type ConditionChecker { get; set; }
}
public static class FilteredSerializer
{
public static string SerializeConditional(IEnumerable<object> input)
{
var matches = (from entry in input
let att = entry.GetType().GetCustomAttribute<ConditionAttribute>()
let hasChecker = att != null && att.ConditionChecker != null
let checker = hasChecker ? (IConiditionChecker)Activator.CreateInstance(att.ConditionChecker) : null
where checker.ShouldBeSerialized(entry)
select entry);
return JsonConvert.SerializeObject(matches);
}
}
[Condition(ConditionChecker = typeof(SomeChecker))]
public class Demo
{
}
Edit: Based on your comment you could do this. 编辑:根据您的评论,您可以执行此操作。 Only must decide wether to use opt-in or opt-out in the
where
-statement. 仅需决定在
where
-statement中是否使用选择加入或选择退出。 It must ether be casted != null && casted.ShouldBeSerialized
or what it currently says. 它必须被
casted != null && casted.ShouldBeSerialized
或它当前所说的内容。
public interface IShouldBeSerialized
{
bool ShouldBeSerialized();
}
public static class FilteredSerializer
{
public static string SerializeConditional(IEnumerable<object> input)
{
var matches = (from entry in input
let casted = entry as IShouldBeSerialized
where casted == null || casted.ShouldBeSerialized()
select entry);
return JsonConvert.SerializeObject(matches);
}
}
public class Demo : IShouldBeSerialized
{
public bool ShouldBeSerialized()
{
return false;
}
}
If you're able to use the JSON.NET serializer, in terms of not serializing specific items within a collection, you could make the main collection non serializable, then add another filtered collection that does serialize. 如果您能够使用JSON.NET序列化程序,就不序列化集合中的特定项目而言,您可以使主集合不可序列化,然后添加另一个进行序列化的过滤后的集合。
public class Manager
{
[JsonIgnore]
public Employee[] Employees { get; set; }
[JsonProperty("Employees")]
public Employee[] SerializableEmployees
{
get { return Employees.Where(e => e.Name != "Bob").ToArray(); }
set { Employees = value; }
}
}
Alternatively, you could mark your class with the [JsonConverter]
attribute and use a custom converter to check your condition. 另外,您可以使用
[JsonConverter]
属性标记您的类,并使用自定义转换器检查您的条件。 A similar approach that ignores a class entirely is detailed here . 这里详细介绍了一种完全忽略类的类似方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.