Search code examples
c#serializationjson.netdatacontractserializer

Wrap primitive type in C# json object serialization and data contract


I'm attempting to strongly type a a string value in a serializable class and I'm having trouble figuring out how to do so.

Below is an example where SomeValue is actually just a string value but I'm attempting to strongly type is to prevent confusion/coding errors with other fields in the same class.

[JsonObject(MemberSerialization.OptIn)]
[DataContract]
public class SomeObject
{
    [DataMember, JsonProperty("some_value")]
    public WrappedString SomeValue { get; set; }
}

The WrappedString class would look something like this:

public class WrappedString
{
    public readonly string Value;

    public WrappedString(string value)
    {
        Value = value;
    }
}

Any thoughts on how to wrap a primitive type and annotate the class that is should use the constructor to deserialize the object?


Solution

  • You can write a custom JsonConverter

    var json = @"{""SomeValue"":""x"",""SomeStringValue"":""y""}";
    var obj = JsonConvert.DeserializeObject<SomeObject>(json);
    

    public class MyConverter : JsonConverter
    {
    
        public override bool CanConvert(Type objectType)
        {
            throw new NotImplementedException();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return new WrappedString((string)reader.Value);
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    public class SomeObject
    {
        [JsonConverter(typeof(MyConverter))]
        public WrappedString SomeValue { get; set; }
        public string SomeStringValue { get; set; }
    }
    
    public class WrappedString
    {
        public readonly string Value;
    
        public WrappedString(string value)
        {
            Value = value;
        }
    }