8

I'm trying to deserialize a JSON file to a c# class. However, my deserialize method always returns null. My JSON file looks like this-

{
  "Products": [
    {
      "ProductID": 994,
      "Name": "LL Bottom Bracket",
      "ProductNumber": "BB-7421",
      "ProductCategoryID": 9,
      "ProductCategory": "Bottom Brackets",
      "ProductModelID": 95,
      "Description": "Chromoly steel."
    },
    {
      "ProductID": 995,
      "Name": "ML Bottom Bracket",
      "ProductNumber": "BB-8107",
      "ProductCategoryID": 9,
      "ProductCategory": "Bottom Brackets",
      "ProductModelID": 96,
      "Description": "Aluminum alloy cups; large diameter spindle."
    }
  ]
}

I'm trying to serialize it to below class-

public class Product
    {
        [JsonProperty("ProductID")]
        public long ProductId { get; set; }

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

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

        [JsonProperty("ProductCategoryID")]
        public long ProductCategoryId { get; set; }

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

        [JsonProperty("ProductModelID")]
        public long ProductModelId { get; set; }

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

        [JsonProperty("Color", NullValueHandling = NullValueHandling.Ignore)]
        public string Color { get; set; }
    }
    public partial class Products
    {
        [JsonProperty("Products")]
        public IEnumerable<Product> ProductsProducts { get; set; }
    }

And finally, I'm using this code to deserialize it, however it returns null for some reason. Can someone please help?

public Products Get()
        {
            var jsonString = IO.File.ReadAllText("ProductsData.json");
            var products = JsonSerializer.Deserialize<Products>(jsonString);
            
            return products;
        }
2
  • It may be an issue with using IEnumerable<Product> for the "Products" property - try either making it an ICollection<Product> or List<Product>, if that doesn't work. For a more elegant solution, I believe there's a way to set a default collection implementation but I don't know what it is off the top of my head. Commented Jan 25, 2021 at 17:41
  • I've tried with List and ICollection but it still doesn't work unfortunately. Commented Jan 25, 2021 at 17:45

4 Answers 4

14

Cause

You are using the JsonProperty attribute from the Netwonsoft.Json package, but the built-in .NET Core/5 deserializer from the System.Text.Json namespace.

How do I know that? Newtonsoft.Json does not have a JsonSerializer.Deserialize overload which takes a single string, and .NET does not contain a JsonPropertyAttribute.

Those two are not compatible. The .NET deserializer ignores your [JsonProperty("Products")] attribute, does not find a propery named ProductsProducts in your JSON and, thus, yields null for that property.


Fix

To use the deserializer from the Newtonsoft.Json package instead, replace

var products = JsonSerializer.Deserialize<Products>(jsonString);

with

var products = JsonConvert.DeserializeObject<Products>(jsonString);

Here is a working fiddle with your code: https://dotnetfiddle.net/27Tz4t

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, that solves it. But lets say, for some reason I didn't to use Newtonsoft.Json, how'd I go about deserializing it?
Then change attribute name to "JsonPropertyName" that is in System.Text.Json.
This solves it for this specific case! But in my case, I had to add JsonPropertyName value with lower case instead of uppercase. So instead of JsonPropertyName("ProductName") I had to write JsonPropertyName("productName"). Maybe because of the JsonSerializerSettings that were specifying CamelCase and JsonPropertyName should override that.
The solution from @Eduard helped solve my problem. That is using "using System.Text.Json.Serialization" with lowercase in JsonPropertyName as "JsonPropertyName("productName")"
5

Using NewtonsoftJson

var products = JsonConvert.DeserializeObject<Products>(jsonString);

Using System.Text.Json

var products = JsonSerializer.Deserialize<Products>(jsonString);
public partial class Products
{
    [System.Text.Json.Serialization.JsonPropertyName("Products")]
    public IEnumerable<Product> ProductsProducts { get; set; }
}

Comments

0

if you have the json response, only use this site for convert Json to c# class

// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
    public class Product    {
        public int ProductID { get; set; } 
        public string Name { get; set; } 
        public string ProductNumber { get; set; } 
        public int ProductCategoryID { get; set; } 
        public string ProductCategory { get; set; } 
        public int ProductModelID { get; set; } 
        public string Description { get; set; } 
    }

    public class Root    {
        public List<Product> Products { get; set; } 
    }

public Products Get()
        {
            var jsonString = IO.File.ReadAllText("ProductsData.json");
            var products = JsonSerializer.Deserialize<Root>(jsonString);
            
            return products;
        }

or use visual studio option Edit-->Paste Special-->Paste JSON as Classes

 public class Rootobject
        {
            public Product[] Products { get; set; }
        }

        public class Product
        {
            public int ProductID { get; set; }
            public string Name { get; set; }
            public string ProductNumber { get; set; }
            public int ProductCategoryID { get; set; }
            public string ProductCategory { get; set; }
            public int ProductModelID { get; set; }
            public string Description { get; set; }
        }




public Products Get()
            {
                var jsonString = IO.File.ReadAllText("ProductsData.json");
                var products = JsonSerializer.Deserialize<Rootobject>(jsonString);
                
                return products;
            }

Comments

0

using System.Text.Json;

According to the offcical microsoft documentation (https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/customize-properties?pivots=dotnet-8-0), "The web default naming policy is camel case."

    JsonSerializerOptions options = new(JsonSerializerDefaults.Web)
    {
        WriteIndented = true
    };

In .NET 8, one can specify the naming policy that JSON can use when serializing/Decerializing

var test  = new HttpResponseMessage
{
    Content = JsonContent.Create(jsonBody, options: new JsonSerializerOptions { DictionaryKeyPolicy = JsonNamingPolicy.CamelCase }),
    StatusCode = httpStatusCode
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.