Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simplify casting of a JToken based on its JTokenType

Tags:

c#

json.net

Is there any solution to refactor following switch/case code in a nicer/shorter way ?

  • property.Value is a JToken
  • opportunity is a CRM Dynamics entity (similar to a Dictionary)

I've tried with following approach without success (it's not acceptable C#)

Type target = property.Value.Type.GetType();
opportunity[property.Key] = property.Value.Value<target>();

Here is the code I'm trying to simplify. (JTokenType.Object and JTokenType.Array are handled in a different way.)

                switch (property.Value.Type)
                {
                    case JTokenType.Boolean:
                        opportunity[property.Key] = property.Value.Value<bool>();
                        break;
                    case JTokenType.Date:
                        opportunity[property.Key] = property.Value.Value<DateTime>();
                        break;
                    case JTokenType.Integer:
                        opportunity[property.Key] = property.Value.Value<int>();
                        break;
                    case JTokenType.String:
                        opportunity[property.Key] = property.Value.Value<string>();
                        break;
                    case JTokenType.Guid:
                        opportunity[property.Key] = property.Value.Value<Guid>();
                        break;
                }

I also tried this as suggested by @diiN_:

opportunity[property.Key] = property.Value.Value<dynamic>();

but it throws an InvalidDataContractException: visual studio exception

like image 266
camous Avatar asked Jul 28 '16 06:07

camous


2 Answers

You could try this in place of your switch statement:

if (property.Value is JValue)
{
    opportunity[property.Key] = ((JValue)property.Value).Value;
}
like image 58
Brian Rogers Avatar answered Oct 16 '22 10:10

Brian Rogers


Not sure if it helps in your situation, but I use a similar piece of code. Maybe give it a try.

// prepare return object
returnResult.Value = new Dictionary<string, string>();

// discover data type
Newtonsoft.Json.Linq.JTokenType parseAs = values[prop].Type;

// parse the data and push it as string into the dictionary
if (parseAs == Newtonsoft.Json.Linq.JTokenType.String)
{
    returnResult.Value.Add(prop, (string)values[prop].Value);
}                        
else if (parseAs == Newtonsoft.Json.Linq.JTokenType.Integer)
{
    returnResult.Value.Add(prop, ((Int16)values[prop].Value).ToString());
}
else if (parseAs == Newtonsoft.Json.Linq.JTokenType.Boolean)
{
    returnResult.Value.Add(prop, ((Boolean)values[prop].Value).ToString());
}
else if (parseAs == Newtonsoft.Json.Linq.JTokenType.Array)
{
    // in case of an array, when value is received by the corresponding method
    // the way of deserializing and parsing will be decided then
    returnResult.Value.Add(prop, values[prop].ToString());
}
like image 43
JohnPan Avatar answered Oct 16 '22 10:10

JohnPan