2016-05-22 35 views
7

我正在用一組類從Newtonsoft.Json創建一個JSON文件。創建的文件非常大,所以我爲屬性創建了JsonProperty以減小尺寸,併爲某些數據類型添加了JsonIgnore和自定義格式。我可以在運行時選擇性地關閉JsonIgnore屬性嗎?

結果是從24MB減少到1MB,這很好;但是,我希望可以在運行時生成完整版本或簡化屬性版本。

是否有反正我可以讓序列化程序可選地使用屬性?

+1

也許表現出你是如何設法定製JSON.Net至今一些代碼。 –

回答

16

是的,這可以使用自定義ContractResolver完成。

您沒有顯示任何代碼,所以我只是舉個例子。假設我有一個類Foo,如下所示。我想要序列化輸出中的IdName屬性,但我絕對不對AlternateNameColor感興趣。我用[JsonIgnore]標出了那些。我想要描述出現,但有時這會變得很長,所以我使用了自定義的JsonConverter來限制它的長度。我也想用簡短的屬性名稱來描述,所以我用[JsonProperty("Desc")]來標記它。

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

當我序列上述的實例...

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); 

...我得到這樣的輸出:

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

現在,讓我們說,我有時會想完整的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

布里爾回答布賴恩,像一個魅力工作,你知道如何關閉[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; }  
} 

如何使用它:

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

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

這不回答被問到的問題。 –

相關問題