User defined struct and default (de)serialization

c#, deserialization, json, serialization

Solution

Right now the serializer does not know how to serialize your struct and you need to tell it how to do it. This is how to do it for Json.NET

One way is to add `JsonPropertyAttribute` to `_value`. That would result in json like this

{"Name":"Some Name","Price":{"_value":2.3}}

Another way would be to create your own JsonConverter that treats your price as a decimal. A simplistic approach could look like this

class PriceConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof( decimal? );
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return serializer.Deserialize( reader ) as Price?;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize( writer, (decimal)((Price)value));
    }
}

And you will need the `JsonConverterAttribute` on your struct

[JsonConverter(typeof(PriceConverter))]
struct Price
{
    //...
}

This will give you json like this

{"Name":"Some Name","Price":2.3}

Both ways serialize and deserialize fine, but the second one creates nicer to read json.

Problem

I have this simple type defined: ``` public struct Price : IComparer<Price>, IEquatable<Price> { private readonly decimal _value; public Price(Price value) { _value = value._value; } public Price(decimal value) { _value = value; } public int Compare(Price x, Price y) { return x._value.CompareTo(y._value); } public int Compare(Price x, decimal y) { return x._value.CompareTo(y); } public int Compare(decimal x, Price y) { return x.CompareTo(y._value); } public bool Equals(Price other) { return _value.Equals(other._value); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; return obj is Price && Equals((Price)obj); } public override int GetHashCode() { return _value.GetHashCode(); } public static implicit operator decimal(Price p) { return p._value; } public static implicit operator Price(decimal d) { return new Price(d); } } ``` When I'm deserializing a given JSON to `Price` it works just fine. But when I'm trying to serialize, it returns an empty `{ }`. I mean, assume having this model: ``` public class Product { public string Name { get; set; } public Price Price { get; set; } } ``` deserializng a JSON like this: ``` { "Name": "Some name", "Price": 2.3 } ``` gives me the correct object. But serializing this sample: ``` var p = new Product { Name = "Some name", Price = 2.3 } ``` creates this json: ``` { "Name": "Some name", "Price": { } } ``` So, how and what can I do to tell serializer libraries (e.g. Json.NET and Jil) how to serialize my custom types? UPDATE: Sample serializing code, using Json.NET ``` var s = JsonConvert.SerializeObject(p); ``` UPDATE2: I dont want to be depend on Json.NET or any other thirdparty libs. So, using `JsonConverter` in Json.NET is not the answer. Thanks in advance.

Original source