简体   繁体   English

使用Json.net有条件地序列化集合中的对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM