2016-04-07 9 views
0

プロパティをスキップすることに関する情報がたくさんありますが、オブジェクトのクラス内の条件に基づいてオブジェクト全体をスキップしたいと思います。私は可能な限り、オブジェクトのクラス内に含まれている解決策が欲しいです。これは私がシリアライズしているmyObjのコレクションです。Json.netを使用してコレクション内のオブジェクトを条件付きでシリアル化

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; 
    } 
} 
+0

パブリックフィールドを使用するのは悪い習慣です。 –

+0

@ErikPhilips私の実際のコードを代表するものではありません。 – Wobbles

答えて

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; 
    } 
} 
+0

2番目のアプローチは面白いですが、おそらくクラスに直接インターフェイス「IShouldSerialize」を適用することで簡単にできます。次に、オブジェクトタイプをチェックし、インターフェースが実装されている場合はプロパティをチェックしてください。それは私が好きな私のアプリケーションを通して再利用可能なままです。 – Wobbles

+0

答えを更新しました。 – Toxantron

-1

あなたは、コレクション内の特定のアイテムをシリアライズないという点で、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; } 
    } 
} 

また、あなたは[JsonConverter]属性を使用してクラスをマークし、あなたの状態をチェックするために、カスタムコンバータを使用することができます。同様のアプローチであるignores a class entirely is detailed here

+0

これは私が知っている私の最初の文で私が言うプロパティを直列化することに関するものです。他のオブジェクトにラップされていない、または含まれていない 'myObj'コレクション内の' myObj'全体をスキップしようとしています。 – Wobbles

+0

LinQを使用したり、独自の拡張機能を書いてみませんか? – Toxantron

+0

@Toxantron linqは、私が今やっていることですが、これを行うために利用できるクラスオブジェクト側のJsonネイティブ機能を見つけようとしていました。私が想像することができる他のものはすべてJsonにあります。 – Wobbles

関連する問題