2016-05-22 9 views
7

私は、一連のクラスからNewtonsoft.Jsonを使用してJSONファイルを作成しています。作成されるファイルは非常に大きいので、サイズを減らすためのプロパティとしてJsonPropertyを作成し、JsonIgnoreといくつかのデータ型のカスタム書式を追加しました。実行時にオプションでJsonIgnore属性を無効にすることはできますか?

結果は24MBから1MBに削減されています。しかし、私は、実行時にフルバージョンまたは縮小プロパティーバージョンのいずれかを生成するオプションを希望します。

シリアライザにオプ​​ションで属性を使用させることはできますか?

+1

。 –

答えて

16

はい、これはカスタムContractResolverを使用して行うことができます。

コードを表示していないので、例を挙げておきます。下に示すようにクラスFooがあるとします。私はIdNameのプロパティをシリアル化出力に入れたいと思いますが、私はAlternateNameColorには興味がありません。私は[JsonIgnore]とマークしました。私は説明が表示されるようにしたいが、時にはこれが本当に長くなることがあるので、長さを制限するためにカスタムJsonConverterを使用した。また、説明に短いプロパティ名を使用したいので、[JsonProperty("Desc")]とマークしました。

{ 
    "Id": 1, 
    "Name": "Thing 1", 
    "Desc": "This is some lengthy text describing Thing 1 " 
} 

さて、私は時々、取得したいとしましょう:私は上記の...

Foo foo = new Foo 
{ 
    Id = 1, 
    Name = "Thing 1", 
    AlternateName = "The First Thing", 
    Description = "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.", 
    Color = "Yellow" 
}; 

string json = JsonConvert.SerializeObject(foo, Formatting.Indented); 

のインスタンスをシリアル化すると...私はこの出力を得る

class Foo 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    [JsonIgnore] 
    public string AlternateName { get; set; } 
    [JsonProperty("Desc")] 
    [JsonConverter(typeof(StringTruncatingConverter))] 
    public string Description { get; set; } 
    [JsonIgnore] 
    public string Color { get; set; } 
} 

私のカスタマイズを無視して、JSONの完全な出力。カスタムContractResolverを使用して、クラスから属性をプログラムで「適用解除する」ことができます。ここでは、リゾルバのコードがあります:

class IgnoreJsonAttributesResolver : DefaultContractResolver 
{ 
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     IList<JsonProperty> props = base.CreateProperties(type, memberSerialization); 
     foreach (var prop in props) 
     { 
      prop.Ignored = false; // Ignore [JsonIgnore] 
      prop.Converter = null; // Ignore [JsonConverter] 
      prop.PropertyName = prop.UnderlyingName; // restore original property name 
     } 
     return props; 
    } 
} 

リゾルバを使用するには、私はJsonSerializerSettingsにそれを追加し、このようなシリアライザに設定を渡す:

JsonSerializerSettings settings = new JsonSerializerSettings(); 
settings.ContractResolver = new IgnoreJsonAttributesResolver(); 
settings.Formatting = Formatting.Indented; 

string json = JsonConvert.SerializeObject(foo, settings); 

出力は今無視プロパティが含まれ、その説明はもはや切り捨てられていない。ここで

{ 
    "Id": 1, 
    "Name": "Thing 1", 
    "AlternateName": "The First Thing", 
    "Description": "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.", 
    "Color": "Yellow" 
} 

全デモ:https://dotnetfiddle.net/WZpeWt

+0

Brillの答えBrianは、魅力のように動作し、[JsonProperty( "ShortName")]属性を無効にする方法を知っていますか? –

+0

はい、リゾルバのループ内に 'prop.PropertyName = prop.UnderlyingName; 'を追加してください。これにより、プロパティは元の名前を使用します。 –

+0

私の回答とデモコードを更新しました。 –

1

Jsonは返品を希望しないプロパティを無視するようにサポートしています。 例はどのようにそれを使用する

class Foo 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 
    public string AlternateName { get; set; }  
} 

:たぶん、あなたはこれまでにJSON.Netをカスタマイズするために管理している方法のいくつかのコードを示し

Foo foo = new Foo 
{ 
    Id = 1, 
    Name = "Thing 1", 
    AlternateName = null, 
}; 

string json = JsonConvert.SerializeObject(foo); 
+1

これは質問された質問には答えません。 –

関連する問題