Search code examples
c#trygetvalue

TryGetValue gives incorrect result


I am trying to get the value from Dictionary(JSON deserialized) and parse it as long.

When I quick viewed the variable I found there is no "M" as part of the out parameter a s given below enter image description here

But when I click into the value, I found "M" being added to the value as given

enter image description here

The problem here is the long.Parse fails when there is "M". If I remove "M" manually long.Parse works fine.

Why this strange behavior? and how to avoid this?

Edit:

Value in payloadJson is

{
  "http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata": "[email protected]",
  "expiry": 1551354842.0,
  "issuedAt": 1551351242.0,
  "notBefore": 1566989642.0,
  "isRefresh": false
}

var payloadData = jsonSerializer.Deserialize<Dictionary<string, object>>(payloadJson);

object exp;
if (payloadData != null && (checkExpiration && payloadData.TryGetValue("expiry", out exp)))
{
    var validTo = FromUnixTime(long.Parse(exp.ToString()));
}

Console app

using JWT;
using JWT.Serializers;
using System.Collections.Generic;
using System.Web.Script.Serialization;

namespace TestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoiYWRtaW5AYWRtaW4uY29tIiwiZXhwaXJ5IjoxNTUxMzU0ODQyLjAsImlzc3VlZEF0IjoxNTUxMzUxMjQyLjAsIm5vdEJlZm9yZSI6MTU2Njk4OTY0Mi4wLCJpc1JlZnJlc2giOmZhbHNlfQ.E-fR8VAFAy-mosEfQC3ZPlN2kZBQg02FLYuChdhqHNhzgVsbIjMXUFLHYowf0aUwQRcyoFR2mpiD_5I6drGdnQ";
            var jsonSerializer = new JavaScriptSerializer();
            IJsonSerializer serializer = new JsonNetSerializer();
            IDateTimeProvider provider = new UtcDateTimeProvider();
            IJwtValidator validator = new JwtValidator(serializer, provider);
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
            var payloadJson = decoder.Decode(token, "GAFaS9W4Ys2AA2VHadPdje9gaeWjY8", true);
            var payloadData = jsonSerializer.Deserialize<Dictionary<string, object>>(payloadJson);

            object exp;
            payloadData.TryGetValue("expiry", out exp);
            var tempExpiry = long.Parse(exp.ToString());
        }
    }
}

Solution

  • M means decimal, D means double, if you want to parse to long, this will work:

    long vOut = Convert.ToInt64(exp);
    

    This is the signature of TryGetValue:

    public bool TryGetValue(TKey key, out TValue value) {
        int i = FindEntry(key);
        if (i >= 0) {
            value = entries[i].value;
            return true;
        }
        value = default(TValue);
        return false;
    }
    

    You should read more about boxing and unboxing.

    You have a variable exp of type object. You have a decimal and you want to put it into exp. You can make a new object that can store the decimal and then you assign a reference to that object to exp. That is boxing.

    Just an example:

    bool x = false; //stack
    object o = b; //box
    bool x2 = (bool)o; //unboxing
    

    why we use boxing? mostly to check nulls:

    if (x == null) //will not compile because bools cannot be of null
    if (o == null) //will compile and always returns false
    

    I hope this helps.