2013-08-29 12 views
6

UPDATEZnalazłem problem - odziedziczyłem po złej klasie, musiał być JsonConverter.niestandardowy serializer dla tylko jednej właściwości w Json.NET

Mam klasy, która ma właściwość Location typu System.Data.Entity.Spatial.DbGeography. Domyślną Json.NET serializer gasi tekst JSON tak:

... 
    "PlaceType": 0, 
    "Location": { 
    "Geography": { 
     "CoordinateSystemId": 4326, 
     "WellKnownText": "POINT (-88.00000 44.00000)" 
    } 
    }, 
    "AddedDT": null, 
    ... 

chcę go zgasić tekst tak:

... 
    "PlaceType": 0, 
    "Location": [-88.00000,44.00000], 
    "AddedDT": null, 
    ... 

... więc wydaje mi się, co należy zrobić, by nadpisać, który konwerter jest aktualnie używany w typie DbGeography.

Przykłady, które dotychczas widziałem używające CustomCreationConverters i ContractResolvers wydają się odnosić do sposobu zastąpienia serializera dla głównej klasy serializowanej, a nie dla typu, który jest tylko właściwością tej klasy. Przykłady, które dotyczą opisywania klasy, która jest nadpisywana, nie działają dla mnie, ponieważ nie definiuję DbGeography w moim kodzie i jest to skutecznie zamknięta klasa, ponieważ nie ma ona konstruktora i może być utworzona tylko za pomocą metod fabrycznych internal.

Czy istnieje sposób na płynne zastosowanie JsonConvertera? Jeśli tak, jak wyglądałby konwerter? Czy po prostu przesłonię metodę WriteJson()?

Odpowiedz

4

Okazuje się, że po prostu musiałem odziedziczyć po JsonConverter zamiast CustomCreationConverter, a wszystko, co próbowałem zmienić, było w porządku.

Nadal nie jestem pewien, czy istnieje sposób na płynne zastosowanie JsonConvertera, ale istnieje inny sposób zastosowania JsonConvertera bez odwoływania się do Json.NET w twoim domenie/projekcie głównym lub zaznaczania twoich klas domen z odniesieniami do biblioteka obwodowa:

var jsonSerializer = new JsonSerializer(); 
jsonSerializer.Converters.Add(new DbGeographyConverter()); 
jsonSerializer.Serialize(jsonWriter, place); 
+1

OK, muszę poczekać dwa dni, aby oznaczyć moje własne pytanie jako udzielone? Czy więc ludzie będą musieli patrzeć na to tak, jakbym wciąż czekał na odpowiedź? Kusiło, aby usunąć całą rzecz. –

+1

Lepiej to zostawić - inni mogą skorzystać z tego, czego się nauczyłeś. Postąpiłeś słusznie, aktualizując pytanie, by powiedzieć, że zostało to rozwiązane w międzyczasie. –

4

Użyj JsonConverterAttribute na nieruchomości i określić niestandardową Converter

na przykład mamy właściwość, która przychodzi w postaci wartości Unix (long int) i szeregować je do .Net DateTime:

[JsonConverter(typeof(UnixTimeJsonConverter))] 
public DateTime Requested { get; set; } 
+0

Czy możesz podać więcej informacji o tym, jak wszystko jest połączone? Zrobiłem dwa najlepsze ujęcia i nie przyniosło to żadnego efektu. Zaktualizuję moje pytanie z dodatkowymi informacjami. –

9

Możesz dodać niestandardowe serializatora do jednego atrybutu tak:

public class Comment 
{ 
    public string Author { get; set; } 

    [JsonConverter(typeof(NiceDateConverter))] 
    public DateTime Date { get; set; } 

    public string Text { get; set; } 
} 

public class NiceDateConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var date = value as DateTime; 
     var niceLookingDate = date.ToString("MMMM dd, yyyy 'at' H:mm tt"); 
     writer.WriteValue(niceLookingDate); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter."); 
    } 

    public override bool CanRead 
    { 
     get { return false; } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(DateTime); 
    } 
} 

Wtedy, kiedy serializacji swój obiekt z JsonConvert.SerializeObject(), zwyczaj serializer zostaną wykorzystane dla własności Date y.