1

I recently solved this error: Type is an interface or abstract class and cannot be instantiated, by using the solution suggested here: Using Json.NET converters to deserialize properties.

Unfortunately I am getting new issues with this. In the code below, Depth gets called as part of the deserialisation, which in turn calls the Prof property which fails because 'this.Profile' is null. ('this.Profile' is a property inherited from the Section class.)

public class TimberSection : Section, IPurlinShape, IEavesBeamShape
    {
        private Profiles.Flat Prof
        {
            get
            {
                var prof = this.Profile as Profiles.Flat;
                if (prof != null)
                    return prof;
                else
                    throw new DataMissingException("Expected Rectangle profile");
            }
        }

        public override double Depth { get { return Prof.Depth; } }
}

I used http://www.jsoneditoronline.org/ to view my object and it seems everything is correct. The profile object that is coming up null when i deserialise, has a value the same as the object prior to serialization.

Below is my method for serialising it, then deserialising it immediately after.

        string serialisedEnquiry = JsonConvert.SerializeObject(enquiry, Formatting.Indented, new JsonSerializerSettings
         {
             TypeNameHandling = TypeNameHandling.Objects,
             TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
         });

        Enquiry enq = JsonConvert.DeserializeObject<Enquiry>(serialisedEnquiry, new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Objects
        });

What am i doing wrong here?

Community
  • 1
  • 1
DBHC
  • 95
  • 12

2 Answers2

0

The two things that pop in my mind are

  • Change Depth from a property to a method

or

  • Make the entire class opt-in and specify which properties should be serialized

You can read more about that here

Smeegs
  • 9,151
  • 5
  • 42
  • 78
  • Thanks for the reply. Am i right in saying your advice is to exclude the code that doesn't hold data anyway and is causing issues by calling objects that may not yet have deserialised? The problem with that is the size of the project - 150 references to Depth alone and there are far more references to other parts of my profile object. Is there a way of getting it to construct the object without actually calling it? I do not understand why the getter is called before full deserialisation anyway. – DBHC Jun 02 '14 at 14:29
  • I'm not saying to exclude the code. I'm saying tell json.net what properties should be serialized. The getter will never get called after full deserialization, because deserialization calls all the getters. I'm not sure what you're intentions are after serializing, but if you don't need `depth`, don't serialize it. – Smeegs Jun 02 '14 at 14:43
  • Even if i do not parse the depth property, it is still called when i deserialise it back into an object. Why is it called before a value for profile is given? I guess that is my real problem. Unless the profile object is not deserialising properly and the first i know of it is when something else is trying to use it. – DBHC Jun 02 '14 at 14:59
  • "it is still called when i deserialise it back into an object" No it doesn't, there's no setter. – Smeegs Jun 02 '14 at 15:04
  • Sorry i mean something (many things actually) are running it. When it responds by returning the value from a not-yet existing object, it fails. You are right in saying all values which are obtained by referencing other values, do no need to be parsed. However, i would not have thought i would have to manually take them all out. "deserialization calls all the getters" - should that not happen after every child of the main object has been deserialised? If it does, perhaps i have another problem. – DBHC Jun 02 '14 at 15:29
  • `ObjectCreationHandling = ObjectCreationHandling.Replace` might be the answer to my problems. I have other errors now so i am not sure if i have simply replaced the issue. Will report back. – DBHC Jun 04 '14 at 11:37
0

ObjectCreationHandling = ObjectCreationHandling.Replace solves this.

DBHC
  • 95
  • 12