2016-05-22 13 views
7

Tworzę plik JSON z Newtonsoft.Json z zestawu klas. Utworzony plik jest bardzo duży, więc utworzyłem JsonProperty dla właściwości, aby zmniejszyć rozmiar i dodano JsonIgnore i niestandardowe formatowanie dla niektórych typów danych.Czy mogę opcjonalnie wyłączyć atrybut JsonIgnore w czasie wykonywania?

Rezultatem jest zmniejszenie z 24 MB do 1 MB, co jest świetne; jednak chciałbym opcji, aby produkować pełną wersję lub zmniejszoną wersję właściwości w czasie wykonywania.

Czy mimo to mogę uzyskać serializator, aby opcjonalnie użyć atrybutów?

+1

może pokazać niektóre kodu, w jaki sposób udało się dostosować Json.NET tak daleko. –

Odpowiedz

16

Tak, można to zrobić za pomocą niestandardowego ContractResolver.

Nie pokazałeś żadnego kodu, więc podam przykład. Załóżmy, że mam klasę Foo, jak pokazano poniżej. Chcę, aby właściwości Id i Name w wynikach serializacji, ale zdecydowanie nie jestem zainteresowany AlternateName i . Zaznaczam je jako [JsonIgnore]. Chcę, aby opis się pojawił, ale czasami może to trwać naprawdę długo, więc użyłem niestandardowego JsonConverter, aby ograniczyć jego długość. Chcę również użyć krótszej nazwy właściwości opisu, dlatego oznaczono ją jako [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; } 
} 

Kiedy serializacji instancję wyżej ...

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

... uzyskać ten wynik:

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

Teraz, powiedzmy, że czasami chce się pełne wyjście JSON, ignorując moje dostosowania. Mogę użyć niestandardowego ContractResolver do programowego "anulowania" atrybutów z klasy. Oto kod dla przelicznika:

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

Aby skorzystać z rozpoznawania nazw, dodaję go do JsonSerializerSettings i przekazać ustawienia do serializatora jak ten:

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

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

Wyjście zawiera teraz ignorowane właściwości, a opis nie jest już obcięty:

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

Pełna demo tutaj: https://dotnetfiddle.net/WZpeWt

+0

Brill odpowiedzieć Brian, działa jak zaklęcie, czy wiesz, jak wyłączyć atrybut [JsonProperty ("ShortName")]? –

+0

Tak, dodaj 'prop.PropertyName = prop.UnderlyingName;' wewnątrz pętli w programie tłumaczącym. Spowoduje to, że nieruchomość będzie używać swojej oryginalnej nazwy. –

+0

Zaktualizowałem moją odpowiedź i kod demonstracyjny. –

1

Json pomoże nam zignorować własność, która nie chce powrotu. Przykład

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

Jak go używać:

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

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

To nie odpowiada na pytanie, które zostało zadane. –

Powiązane problemy