1

​Using VS 2019, Dot Net Core, Azure Function. HttpTrigger.

I've worked with JSON files previously in .Net Desktop and Server app dev. So, don't know what's happening in Azure and with Newtonsoft. When I try and dump the value of wht.YourName.last, I get the error,

Object reference not set to an instance of an object

which confuses me because in my other programming with System.Text.Json, if I have a class model for a JSON file structure that has a child, the usual function call I use, which is JsonSerializer.Deserialize<jsonclass>(jsonstring), it has no problem setting up the child of the parent parent (reference below, class structure).

Is there a difference between the two function implementations, JsonConvert.DeserializeObject and JsonSerializer.Deserialize?

All of the code samples I've seen seem for Newtonsoft's method seem straight forward as its counterpart in dot net, which doesn't require me to have to do any pre-initalization of the NameBlock class/object.

Hope I explained that well enough considering my brain is kind of fried learning Azure.

Here is my deserialization code using Newtonsoft's method:

string requestBody = await new StreamReader(req.Body).ReadToEndAsync();    
WebhookTest wht = JsonConvert.DeserializeObject<WebhookTest>(requestBody);

Raw dump of httprequest.Body:

{
   "FormID":"1081011",
   "UniqueID":"178165183",
   "support_request":"",
   "your_name":{
      "first":"Testy",
      "last":"Tester"
   },
   "email":"jxxxx@gxxxcxxxaxxxxxxxx.com",
   "phone":"(111) 867-5309",
   "upload_a_file_optional":"",
   "request_details":"Testing latest revision of Azure function that deserializes JSON data into a class object."
}

This is what my class structure looks like:

public class NameBlock    
{    
public string first { get; set; }    
public string last { get; set; }             
} 

public class WebhookTest  
{
   public string FormID { get; set; }                 
   public string UniqueID { get; set; }                 
   public string SupportRequest { get; set; }                 
   public NameBlock YourName { get; set; }                 
   public string Email { get; set; }                 
   public string Phone { get; set; }  
          
   [JsonProperty("Uploadafile(optional)")]                 
   public string UploadafileOptional { get; set; }                 
   public string RequestDetails { get; set; }             
}
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
GCDevOps
  • 45
  • 6
  • 1
    Serializers don't usually throw null reference exceptions, the code around them might, or passing an null reference to the will – TheGeneral Oct 15 '20 at 23:25
  • @TheGeneral I have the deserializing call and the log dump for every class member in a try-catch block. I'm able to dump the values of every member of the WebhookTest class until I get to the first YourName element. That's when I get the error. It's strange. I might just dump Newtonsoft and go back to System.Text.Json (shrugs shoulders) – GCDevOps Oct 15 '20 at 23:53
  • I seem to recall that underscores in a property name change how JSON.NET deserializes the value, but I'm not finding a reference to back me up on that. Closest I see is https://www.newtonsoft.com/json/help/html/NamingStrategySnakeCase.htm and/or https://stackoverflow.com/a/44633105/534109 – Tieson T. Oct 16 '20 at 00:01
  • Hi, please refer to the solution I provided below. If it helps your problem, please [accept](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235) it as answer(click on the check mark beside my answer to toggle it from greyed out to filled in). Thanks in advance~ – Hury Shen Oct 16 '20 at 02:47
  • Thanks everyone for your feedback. Hury Shen's suggestion resolved my issue. I'm rocking and rolling now. Very much appreciated! – GCDevOps Oct 16 '20 at 13:00

1 Answers1

1

The reason for the error Object reference not set to an instance of an object is the code can't find wht.YourName(because wht.YourName is null). Please change your class structure to:

public class NameBlock
{
    public string first { get; set; }
    public string last { get; set; }
}

public class WebhookTest
{
    public string FormID { get; set; }
    public string UniqueID { get; set; }
    public string SupportRequest { get; set; }

    [JsonProperty(PropertyName = "your_name")]
    public NameBlock YourName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }

    [JsonProperty("Uploadafile(optional)")]
    public string UploadafileOptional { get; set; }
    public string RequestDetails { get; set; }
}

Just add a line [JsonProperty(PropertyName = "your_name")]

By the way:

When we use System.Text.Json, it will relate your_name(in request json) with YourName(in class structure) automatically according to hump law. But when we use Newtonsoft.Json, it can't do it. So it can't relate your_name with YourName. We need to add [JsonProperty(PropertyName = "your_name")] to let the code know how to relate the two properties.

Hury Shen
  • 14,948
  • 1
  • 9
  • 18
  • Thanks a heap! Had to add the attribute to SupportRequest and RequestDetails members as well and I'm now seeing all the data in the log dump. Also, thank you for the additional sanity check on System.Text.Json. Did not know that it was spoiling me that way. Now I know. Cheers! – GCDevOps Oct 16 '20 at 12:59