Search code examples
c#json.net

Deserialize json.net property as uppercase


Given the following POCO:

public class AggV2
{
    [JsonProperty("T")]
    public string Ticker { get; set; }
    [JsonProperty("v")]
    public decimal Volume { get; set; }
    [JsonProperty("o")]
    public decimal Open { get; set; }
    [JsonProperty("c")]
    public decimal Close { get; set; }
    [JsonProperty("h")]
    public decimal High { get; set; }
    [JsonProperty("l")]
    public decimal Low { get; set; }
    [JsonProperty("t")]
    [JsonConverter(typeof(UnixMillisecondsConverter))]
    public DateTimeOffset Timestamp { get; set; }
}

I have seen the 3rd party data provider is sending mixed case for the same ticker, i.e. MsFT and MSFT - the is causing nightmares with MSSQL key constraints!

First step is to filter to a common case, so that the Ticker property value would always be MSFT for the above example.

How can I ensure Ticker is always serialized as uppercase please?


Solution

  • I wrote the following converter, would this be the best practice way or have i reinvented the wheel?

    public class AggV2
    {
        [JsonProperty("T")]
        [JsonConverter(typeof(UppercaseStringConverter))]
        public string Ticker { get; set; }
        [JsonProperty("v")]
        public decimal Volume { get; set; }
        [JsonProperty("o")]
        public decimal Open { get; set; }
        [JsonProperty("c")]
        public decimal Close { get; set; }
        [JsonProperty("h")]
        public decimal High { get; set; }
        [JsonProperty("l")]
        public decimal Low { get; set; }
        [JsonProperty("t")]
        [JsonConverter(typeof(UnixMillisecondsConverter))]
        public DateTimeOffset Timestamp { get; set; }
        [JsonProperty("n")]
        public int Samples { get; set; }
    }
    
    public class UppercaseStringConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(string);
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (value is string str)
                writer.WriteValue(str.ToUpper());
            else
                throw new JsonSerializationException("Expected date object value.");
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            bool nullable = Nullable.GetUnderlyingType(objectType) != null;
    
            if (reader.TokenType == JsonToken.Null)
            {
                if (!nullable)
                {
                    throw new JsonSerializationException($"Cannot convert null value to {objectType}.");
                }
                return null;
            }
    
            if (reader.TokenType == JsonToken.String)
                return ((string)reader.Value).ToUpper();
            else
                throw new JsonSerializationException($"Unexpected token parsing date. Expected String, got {reader.TokenType}.");
        }
    }