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

时间:2016-04-07 23:37:23

标签: c# json.net

有很多关于根据条件跳过属性的信息,但我想根据对象类中的条件跳过整个对象。如果可能的话,我想要一个包含在对象类中的解决方案。请记住,这是我正在序列化的myObj的集合。

public class myObj
{
    bool conditional;
    ShouldSerialize()
    {
        return conditional;
    }
}

或者

public class myObj
{
    [JsonCondition]
    public bool conditional{get;}
}

甚至

[JsonCondition(typeof(MyConditionChecker))]
public class myObj
{
    public bool conditional{get;}
}

class MyConditionChecker: JsonCondition
{
    public override bool CanConvert(object sourceObj)
    {
        return (sourceObj as myObj).conditional;
    }
}

2 个答案:

答案 0 :(得分:1)

我从您的评论中得到的结果是,您最好在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;
}

您也可以使用反射方法替换接口,但请记住性能损失。

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
{
}

修改:根据您的评论,您可以执行此操作。只能在where声明中决定使用选择加入还是选择退出。它必须是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;
    }
}

答案 1 :(得分:-1)

如果您能够使用JSON.NET序列化程序,就不序列化集合中的特定项而言,您可以使主集合不可序列化,然后添加另一个序列化的过滤集合。

viewDidLoad

或者,您可以使用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; } } } 属性标记您的课程,并使用自定义转换器检查您的情况。 ignores a class entirely is detailed here的类似方法。