Serialize an object as null based on one of its properties

In the JsonConverter WriteJson custom method of JsonConverter WriteJson can I appeal the default serialization behavior of an object from JsonConverter ?

That is, can I postpone to serialization, which would have happened if the user converter had not been registered?

More details

Given the price class

 public class Price { public string CurrencyCode; public decimal Amount; } 

The normal behavior of Newtonsoft Json.NET is to serialize the Price instance as null only when the link is null. In addition, I would like to serialize Price instances as null at any time to Price.Amount equal to zero. Here is what I have worked so far ( full source )

 public class PriceConverter : JsonConverter { // ... public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer) { var price = (Price)value; if (0 == price.Amount) { writer.WriteNull(); return; } // I'd like to replace the rest of this method with an appeal to the // default serialization behavior. writer.WriteStartObject(); writer.WritePropertyName("amount"); writer.WriteValue(price.Amount); writer.WritePropertyName("currencyCode"); writer.WriteValue(price.CurrencyCode); writer.WriteEndObject(); } // ... } 

The last part of this implementation is fragile. If, for example, I added fields to Price , my serialization would be broken (and I don’t know how a good way to write a test that detects a gap).

My serializer has several types of behavior configured in a separate assembly through JsonSerializerSettings that I need to save (for example, object property names). I cannot add a direct relationship between the two. In fact, I use the [JsonConverter(typeof(PriceConverter))] attribute to indicate that my custom converter should be used for Price .

+4
source share
2 answers

A workaround that allows converters to get settings - you can use a serialization context.

Setup:

 var settings = new JsonSerializerSettings { /*...*/ }; settings.Context = new StreamingContext(StreamingContextStates.All, settings); 

In the converter:

 var settings = (JsonSerializerSettings)serializer.Context.Context; 

I feel dirty when I do this, though.

+2
source

What is wrong with this approach?

 public static JsonSerializerSettings MySettings() { return new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), TypeNameHandling = TypeNameHandling.All, DefaultValueHandling = DefaultValueHandling.Ignore, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind, }; } 

In your PriceConverter :

 if (0 == price.Amount) { writer.WriteNull(); return; } else { writer.WriteRaw(JsonConvert.SerializeObject(value, Somewhere.MySettings())); return; } 

And in your program:

  public static void Custom(Price p) { var settings = Somewhere.MySettings(); settings.Converters = new List<JsonConverter> { new PriceConverter() }; Console.WriteLine("custom: " + JsonConvert.SerializeObject(p, settings)); } 
0
source

Source: https://habr.com/ru/post/1484712/


All Articles