-3

I keep getting following error:

Object reference not set to an instance of an object

This is my Json string in a file at C:\part_param.json

{    
    "part_parameters" : {
        "bar_diameter" : 300.4,
        "core_height" : 132,
       "roughing_offset" : 0.3    
    } 
}

and the code I am using is as follows:

    public class PLMpartParameter
    {
        public class Parameters
        {
            public float bar_diameter;
            public float core_height;
            public float roughing_offset;

            public Parameters(float barD, float coreH, float roughingO)
            {
                bar_diameter = barD;
                core_height = coreH;
                roughing_offset = roughingO;
            }
        }
        public Parameters parameters;

        public PLMpartParameter(Parameters param)
        {
            parameters = param;
        }

    }


    public static void LoadJson()
    {
        using (System.IO.StreamReader r = new System.IO.StreamReader(@"C:\part_param.json"))
        {
            string json = r.ReadToEnd();
            _logger.Info(string.Format("Read entire file complete. File Values: {0}", json));

            try
            {
                PLMpartParameter part = Newtonsoft.Json.JsonConvert.DeserializeObject<PLMpartParameter>(json);

            }
            catch (Exception e)
            {
                _logger.Info(string.Format("Read Json failed {0}", e.Message));
            }
        }

What am I missing here?

sanchit
  • 19
  • 3
  • the line throwing the exception may be ? are you sure _logger is set ? – tschmit007 Mar 14 '19 at 14:29
  • Which line throws the error? – ADyson Mar 14 '19 at 14:30
  • 3
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Sinatr Mar 14 '19 at 14:30
  • 6
    You have a field called `parameters`, but your JSON has a property called `part_parameters`. (I'd personally urge you to make the `Parameters` class top-level, and use properties instead of public fields, with `[JsonProperty]` to specify the name in the JSON file so you can keep the code compliant with .NET naming conventions.) – Jon Skeet Mar 14 '19 at 14:30
  • 2
    As @JonSkeet is here, I deleted my answer. ;) – Prasad Telkikar Mar 14 '19 at 14:31
  • This line throws error PLMpartParameter part = Newtonsoft.Json.JsonConvert.DeserializeObject(json); – sanchit Mar 14 '19 at 14:32
  • Also once you fix that, the JSON will not deserislise because the JSON structure doesn't match the class structure. I'm thinking particularly of "part_parameters" in the JSON vs "public Parameters parameters" in the C# - the property names need to match. Also not sure what newtonsoft will do with a class which has no parameterless constructor. – ADyson Mar 14 '19 at 14:33
  • @PrasadTelkikar I think your answer is helpful, although I used Paste Special, Past JSON As Classes to obtain the same code. Although, it is part_parameters and probably fields vs. properties that are the issues that need to be identified. – Andy G Mar 14 '19 at 14:33
  • Ok Jon. I will rename the properties. Would that help with the error though? – sanchit Mar 14 '19 at 14:35
  • @sanchit : code example link https://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx – IMParasharG Mar 14 '19 at 14:36
  • @PrasadTelkikar okay, good, but I think it would also need to address what the issues are. Namely the naming part_parameters, use of fields vs. properties, removing the ctor, etc.. – Andy G Mar 14 '19 at 14:42

4 Answers4

2

I think the problem is your property is called 'parameters' but in your json it's 'part_parameters'.

1

Quoting Prasad Telkikar's answer as that fixed it right away

Use json2csharp to get model for your json file, then deserialize your json. You can use visual studio in build function to create class i.e. Edit -> Paste special -> Paste JSON as Class

Here is class

> public class PartParameters {
>     public double bar_diameter { get; set; }
>     public int core_height { get; set; }
>     public double roughing_offset { get; set; } }
> 
> public class RootObject {
>     public PartParameters part_parameters { get; set; } }

To deserialize, use below code

PLMpartParameter part = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

My final code looks like this, and its working!!

    public class PartParameters
    {
        public double bar_diameter { get; set; }
        public int core_height { get; set; }
        public double roughing_offset { get; set; }
    }

    public class RootObject
    {
        public PartParameters part_parameters { get; set; }
    }

    public static void LoadJson()
    {
        using (System.IO.StreamReader r = new System.IO.StreamReader(@"C:\part_param.json"))
        {
            string json = r.ReadToEnd();
            try
            {
                RootObject part = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(json);

                _logger.Info(string.Format("list values : bardiameter: {0}, coreHeight: {1}, roughingOffset: {2}", 
                    part.part_parameters.bar_diameter,part.part_parameters.core_height, part.part_parameters.roughing_offset));
            }
            catch (Exception e)
            {
                _logger.Info(string.Format("Read Json failed {0}", e.Message));
            }

        }

    }
sanchit
  • 19
  • 3
  • You also need `[JsonProperty("part_parameters")]` – Andy G Mar 14 '19 at 14:45
  • Yes! I am new to Json, so didn't know that i need to format my properties like this – sanchit Mar 14 '19 at 14:46
  • This is saying "what I will call PartParameters is named in the JSON as part_parameters". You can add the same for bar_diameter etc., to retain C# naming. – Andy G Mar 14 '19 at 14:48
1

You must add a JSON attribute above your property, so that your properties are recognized when deserializing your object.

you will find an example just below

public class Parameters
{
    [JsonProperty("bar_diameter")]
    public float bar_diameter;
    [JsonProperty("core_height")]
    public float core_height;
    [JsonProperty("roughing_offset")]
    public float roughing_offset;

    public Parameters(float barD, float coreH, float roughingO)
    {
        bar_diameter = barD;
        core_height = coreH;
        roughing_offset = roughingO;
    }
}
sayah imad
  • 1,507
  • 3
  • 16
  • 24
0

You have a few issues with your code:

  1. You need to have default constructors for the classes (this is due to how serializers work with types - they are not going to understand your class-specific paramaterised constructor).
  2. Your fields need to be settable properties (Just add {get;set;} and you should be good to go).
  3. I would suggest you decorate the parameters property with [JsonProperty("part_parameters")] to get the deserialization behaviour you're expecting.
toadflakz
  • 7,764
  • 1
  • 27
  • 40
  • I see. I tried the get; set;, but that didn't seem to do anything. But as you mentioned in 3rd suggestion to decorate with [JsonProperty("part_parameters")], that did the trick – sanchit Mar 14 '19 at 14:44