1

So, what I want is to serialise and deserialise some JSON using a generic field wrapper class.

I do not want to write some custom JsonConverter class.

I do wish to keep it simple and write some implicit operator type conversion. The following minimal piece of C# code is where I am at now .... just enough to demonstrate the issue and no more. Don't overlook the implicit operators.

using Newtonsoft.Json;
using System;

namespace test
{
    public struct SofT<T>
    {
        [JsonProperty]
        public T TValue { get; set; }

        public static implicit operator SofT<T>(string jtoken)
        {
            return new SofT<T>()
            {
                TValue = (T)Convert.ChangeType(jtoken, typeof(T))
            };
        }

        public static implicit operator string(SofT<T> soft)
        {
            return soft.TValue?.ToString() ?? "";
        }
    }


    [JsonObject(MemberSerialization.OptIn)]
    public class Something
    { 
        [JsonProperty]
        public SofT<int> TestStructInt { get; set; }

        [JsonProperty]
        public SofT<decimal> TestStructDecimal { get; set; }
    }

    public class Program
    {
        public void Run()
        {
            var json = "{ \"TestStructInt\" : \"12\", \"TestStructDecimal\" : \"3.45\"}";
            var modelDeserialised = JsonConvert.DeserializeObject<Something>(json);
            var modelReserialised = JsonConvert.SerializeObject(modelDeserialised);
            Console.WriteLine(modelReserialised);
        }

        static void Main(string[] args)
        {
            new Program().Run();
        }
    }
}

The JSON string is deserialised perfectly. The model object is not reserialised correctly.

The string that is spat out to the console is:

quote {"TestStructInt":{"TValue":12},"TestStructDecimal":{"TValue":3.45}}

The string I expect, or better put want, to be spat out to the console is the same structure in the source JSON, ie:

quote {"TestStructInt":"12"},"TestStructDecimal":"3.45"}}

I am asking for a second pair of eyes to point out my error (and yes I can see the error, the annotation of Value with [JsonProperty], but it seems necessary for default serialisation).

Charlieface
  • 52,284
  • 6
  • 19
  • 43
  • Does this answer your question? [Json.NET: How to perform implicit conversion of an object before serializing?](https://stackoverflow.com/questions/37982581/json-net-how-to-perform-implicit-conversion-of-an-object-before-serializing) – Charlieface Oct 28 '21 at 20:47
  • You could do it without a converter, by using another property, but personally I think a converter is cleaner. Maybe make a generic converter that can lookup the conversion function using reflection – Charlieface Oct 28 '21 at 20:51
  • Thanks Charlie .... the code I am writing will be T4 generated and it would be mighty convenient to autogen implicit converters and the same time. Furthermore it should be possible, as demonstrated with the deserialisation. My gut feeling is I am "almost there" with the implicit conversion even in this trivial example. The fallback is a custom JsonConverter, that I have already coded, albeit only for ints and decimal. Perhaps generics for the converter are a way forward for a single converter. I may monkey around with the approach later today. Thanks for your reply and suggestions – Michael D O'Shea Oct 29 '21 at 06:13
  • It can't be done, for the simple reason that the serializer has no idea what you want to convert it to. For deserialization, it works because it's trying to force that value into the property, which it can't and therefore looks for a conversion operator. You are going to need one of the two options outlined in the other answer. I can write a generic converter if that's what you want – Charlieface Oct 29 '21 at 09:53
  • I'm going to have a stab at writing a generic converter as writing one for each value or other type would be a complete unmaintainable mess. If you have written a JsonConverter previously or want to have a go at it, do so and I will plagiarise your code :-) Might be worth your while to message me privately on another forum too ... I am not too hard to find. – Michael D O'Shea Oct 29 '21 at 16:04

0 Answers0