2

I have this code :

class Sometype
{
    public Number pos { get; set; }
}

class Number
{
    private uint num;

    private Number(uint num)
    {
        this.num = num;
    }

    public static implicit operator uint(Number sid)
    {
        return sid.num;
    }

    public static implicit operator Number(uint id)
    {
        return new Number(id);
    }
}

And this json : {"pos":123}

When I try to deserialize this, I get a JsonException Error converting value 123 to type 'Tester2.Program+Number'.. Please advise me.

blower135
  • 21
  • 2
  • Have you tried `public static implicit operator Number(string id) { return new Number(uint.Parse(id)); }`? – Clay Ver Valen Dec 08 '15 at 20:16
  • I don't quite understand how that would work. In the json, `123` *is* a number. – blower135 Dec 08 '15 at 20:17
  • Yes, it is a number. But if for any reason the JsonType thinks it is a string this would be a very quick and easy check. – Clay Ver Valen Dec 08 '15 at 20:18
  • Tried it. Same error. – blower135 Dec 08 '15 at 20:20
  • Figured it was worth a shot. But did (hopefully) post a good answer for you below. – Clay Ver Valen Dec 08 '15 at 21:06
  • The answers below may help to deserialize, but in my case I want to be able to serialize the object as well. For an answer that solves that take a look here: https://stackoverflow.com/questions/24472404/json-net-how-to-serialize-object-as-value –  Jun 09 '17 at 18:31

2 Answers2

3

If you add an implicit (or explicit) conversion from long to Number, this will work fine.

JSON.NET works with longs when dealing with integral types, not uints, and so your cast from uint is never called. For example:

class Number
{
    private uint num;

    private Number(uint num)
    {
        this.num = num;
    }

    public static implicit operator Number(uint id)
    {
        return new Number(id);
    }

    public static implicit operator Number(long id)
    {
        return new Number((uint)id);
    }

    public static implicit operator uint(Number sid)
    {
        return sid.num;
    }
}

Obviously this could result in overflow errors, so be careful. Another solution would be to create a custom converter to handle this (might be worth looking into if you're serializing and deserializing this type).

Here's a working example: https://dotnetfiddle.net/MP4E3N

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
0

Full source for Console app/Any CPU is below. If this doesn't work for you change the declaration of pos to be of type object and then do pos.GetType() to see what you are actually getting if not an Int64.

using System;
using Newtonsoft.Json;


class Sometype
{
    public Number pos { get; set; }
}

class Number
{
    private uint num;

    private Number(uint num)
    {
        this.num = num;
    }

    public static implicit operator uint(Number sid)
    {
        return sid.num;
    }

    public static implicit operator Number(Int64 id)
    {
        return new Number((uint)id);
    }

}

class Program
{
    static void Main()
    {
        Sometype thing = JsonConvert.DeserializeObject<Sometype>("{\"pos\":123}");
    }
}
Clay Ver Valen
  • 1,033
  • 6
  • 10