Home > OS >  How to cast Newtonsoft.Json.Linq.JObject to complex type?
How to cast Newtonsoft.Json.Linq.JObject to complex type?

Time:05-23

Given the following c# code:

using Newtonsoft.Json;
using System;

namespace ConsoleApp2
{
    internal class Program
    {
        public class BatteryStatus
        {
            // The battery level reports percentage of the full battery.The field can take values from 0 to 100% (0x00 – 0x64).
            // The value 0xFF indicates a battery low warning.
            public byte BatteryLevel { get; set; }

            public bool LowBatteryWarning { get; set; }

            public DateTime TimestampUtc { get; set; }

            public BatteryStatus(byte batteryLevel)
            {
                TimestampUtc = DateTime.UtcNow;
                if (batteryLevel == 0xff)
                {
                    LowBatteryWarning = true;
                    batteryLevel = 0;
                }
                BatteryLevel = batteryLevel;
            }
        }

        static void Main(string[] args)
        {
            BatteryStatus batteryStatus = new BatteryStatus(40);
            string json = SaveObjectToJsonString(batteryStatus);
            Object obj = ReadObjectFromJsonString(json);
        }

        static string SaveObjectToJsonString(Object obj)
        {
            string json = JsonConvert.SerializeObject(obj);
            return json;
        }

        static Object ReadObjectFromJsonString(string json)
        {
            var obj = JsonConvert.DeserializeObject(json);
            return obj;
        }

    }
}

Without changing the SaveObjectToString or ReadObjectFromString functions (and pretend that you didn't even see the source code for these), how can obj be converted to an object of the BatteryStatus class?

Attempting to cast directly like this:

batteryStatus = (BatteryStatus)obj;

result in the following error:

Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'BatteryStatus'.

CodePudding user response:

You can use JObject.ToObject method.

static void Main(string[] args)
        {
            BatteryStatus batteryStatus = new BatteryStatus(40);
            string json = SaveObjectToJsonString(batteryStatus);
            var obj = ReadObjectFromJsonString(json);
            JObject jObj = obj is JObject ? (JObject)obj : JObject.FromObject(obj);
            var deserializedBatteryStatus = jObj.ToObject<BatteryStatus>();
        }

CodePudding user response:

Would something using generics work for your use case?

We could change your ReadObjectFromJsonString and SaveObjectToJsonString to use generics...

static string SaveObjectToJsonString<T>(Object obj) where T: class
        {
            string json = JsonConvert.SerializeObject(obj);
            return json;
        }

        static T ReadObjectFromJsonString<T>(string json) where T: class
        {
            var obj = JsonConvert.DeserializeObject<T>(json);
            return obj;
        }

Then the class can be specified when you call those functions -

BatteryStatus status = new BatteryStatus(40);
                string str = SaveObjectToJsonString<BatteryStatus>(status);
                BatteryStatus readBack = ReadObjectFromJsonString<BatteryStatus>(str);

CodePudding user response:

try this

BatteryStatus BatteryStatus = ((JObject)obj).ToObject<BatteryStatus>();
  • Related