0

I want to serialize and deserialize a c# model using Newtonsoft. The serialization works well, but the deserialization throws an error: Error converting value "1" to type ProjectNamespace.CapturedObject'. Path '', line 14, position 19.' Visual Studio also says: Inner Exception: ArgumentException: Could not cast or convert from System.String to ProjectNamespace.CapturedObject. I need help in interpreting this error message. Below are the relevant classes ... The error is thrown in the Json Extension Converter on the line return new Collection<T> { token.ToObject<T>() }; which I got from here

Serialization/Deserialization

public class JsonSession
    {    
        private readonly JsonSerializer serializer = new JsonSerializer();

        private static JsonSerializerSettings GetJsonSerializerSettings()
        {
            JsonSerializerSettings settings = new JsonSerializerSettings()
            {
                TypeNameHandling = TypeNameHandling.Objects,
                Converters = new List<JsonConverter>
                {
                    new StringEnumConverter()
                }
            };
            return settings;
        }

        JsonSerializerSettings writerSettings = GetJsonSerializerSettings();

        /// <summary>
        /// Constructor
        /// </summary>
        public JsonSession() { }


        /// <summary>
        /// Deserialization
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public JsonModel OpenModel(string filePath)
        {
            using (StreamReader file = File.OpenText(filePath))
                return (JsonModel)serializer.Deserialize(file, typeof(JsonModel));
        }


        /// <summary>
        /// Serialization
        /// </summary>
        /// <param name="model"></param>
        /// <param name="filePath"></param>
        public void SaveModel(JsonModel model, string filePath)
        {
            using (StreamWriter file = File.CreateText(filePath))
            using (var writer = new JsonTextWriter(file))
            {
                writer.Formatting = Formatting.Indented;
                serializer.Serialize(writer, model);
            }
        }

    }

JsonModel

public class JsonModel {

    [JsonProperty("head")]
    public JsonHeader Header { get; set; } = new JsonHeader();

    
    [JsonProperty("application")]
    public JsonApplication Application { get; set; } = new JsonApplication();

    
    [JsonProperty("knowledgebase")]
    public JsonBase JsonBase { get; set; } = new JsonBase();

    #endregion

    #region Constructors
    public JsonModel() { }

    public JsonModel(JsonHeader header, JsonBase jsonBase)
    {
        this.Header = header;
        this.JsonBase = jsonBase;
    }
}

Knowledge Base

#region Public Members

        
        [JsonProperty("features")]
        [JsonConverter(typeof(JsonConverterExtension<CapturedObject>))]
        public Collection<CapturedObject> Features { get; set; } = new Collection<CapturedObject>();

        
        [JsonProperty("faces")]
        [JsonConverter(typeof(JsonConverterExtension<CapturedObject>))]
        public Collection<CapturedObject> Faces { get; set; } = new Collection<CapturedObject>();

        
        [JsonProperty("edges")]
        [JsonConverter(typeof(JsonConverterExtension<CapturedObject>))]
        public Collection<CapturedObject> Edges { get; set; } = new Collection<CapturedObject>();

        
        [JsonProperty("vertices")]
        [JsonConverter(typeof(JsonConverterExtension<CapturedObject>))]
        public Collection<CapturedObject> Vertices { get; set; } = new Collection<CapturedObject>();

        
        [JsonProperty("dimensions")]
        [JsonConverter(typeof(JsonConverterExtension<CapturedObject>))]
        public Collection<CapturedObject> Dimensions { get; set; } = new Collection<CapturedObject>();
        
        #endregion

        #region Constructors

        public JsonBase() { }

        #endregion
    }

Captured Object Class

public class CapturedObject
{

    [JsonProperty("pseudonym")]
    public string Pseudonym { get; set; }

    [JsonProperty("name")]
    public string ObjectName { get; set; }

    [JsonProperty("type")]
    public ModelObjectType ObjectType { get; set; }

    #endregion

    #region Constructor

    public CapturedObject() { }

}

#Json Converter Extension

class JsonConverterExtension<T> : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(List<T>));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JToken token = JToken.Load(reader);
            if (token.Type == JTokenType.Array)
            {
                return token.ToObject<Collection<T>>();
            }
            return new Collection<T> { token.ToObject<T>() };
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            List<object> list = new List<object>();

            if (value is IEnumerable)
            {

                var enumerator = ((IEnumerable)value).GetEnumerator();
                while (enumerator.MoveNext())
                {
                    list.Add(enumerator.Current);
                }
            }

            // List<T> list = (List<T>)value;
            if (list.Count == 1)
            {
                value = list[0];
            }
            serializer.Serialize(writer, value);
        }
    }

#EDIT : Sample Json

    {
  "head": {
    "author": "User",
    "date": "8-20-2020",
    "application": "App",
    "cad": "swx",
    "name": "C:\\Users\\User\\Desktop\\so.json",
    "location": "C:\\Users\\User\\Desktop\\so.json"
  },
  "application": {
    "name": "App",
    "language": "English",
    "versions": "1",
    "extensions": ".json"
  },
  "knowledgebase": {
    "features": [
      {
        "pseudonym": "Caster Casing",
        "name": "BoddExtrude1",
        "type": 22
      },
      {
        "pseudonym": "Wheel",
        "name": "Revolve2",
        "type": 22
      },
      {
        "pseudonym": "Corner Vertex",
        "name": "Fillet1",
        "type": 22
      }
    ],
    "vertices": {
      "pseudonym": "Corner Vertex",
      "name": "SpecialVertex",
      "type": 3
    },
    "dimensions": {
      "pseudonym": "Cool Dimension",
      "name": "D1@Sketch2",
      "type": 14
    }
  }
}
Dorogz
  • 13
  • 1
  • 5
  • *"Error converting value "1" to type ProjectNamespace.CapturedObject'. Path '', line 14, position 19.'"* sounds to me as if your data does not exactly look like you expect it to. Something you are trying to convert to a `CapturedObject`has the value "1" - which cannot be converted to a `CapturedObject` – Paul Kertscher Aug 20 '20 at 04:20
  • Please add the data you are trying to deserialize – Paul Kertscher Aug 20 '20 at 04:20
  • @Paul Kertscher The json file has no value "1". Well, the type could be 1 but this occurs only when the type 1 is captured in the application which is not always the case ... – Dorogz Aug 20 '20 at 05:25
  • Actually there is a value "1" for `application.versions`, but the corresponding model is not included... also it seems a pretty solid match for "line 14, position 19", even though there seems to be some mis-alignment which might be related to copy-paste changes – grek40 Aug 20 '20 at 06:41
  • @grek40: Some people have sight but can't see ... I am probably a perfect example! Your comment pointed to the problem and opened the door to solving other problems. Thanks! Would you please post an answer for me to mark as the correct answer? – Dorogz Aug 20 '20 at 07:27
  • Uff, hard to write a good answer here... the answer would basically be "if the error mentions a line and position, look at that exact line and position for potential errors" ;) Anyway, glad you figured it out. – grek40 Aug 20 '20 at 10:25

0 Answers0