2

In my .Net Core 3.1 Web app I have a Class shared by Backend and Frontend that looks like this

public class Order
{
    [Key]
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public DateTime OrderTime { get; set; }
    public int UserId { get; set; }
    public int Vat { get; set; }
    [NotMapped]
    public Dictionary<string, int> Products { get; set; }
    public int Discount { get; set; }
    public float ShippingPrice { get; set; }
    public bool Shipped { get; set; }
    public bool Cancelled { get; set; }
    public string CancelReason { get; set; }

    public Order()
    {

    }
}

And on Frontend I am using HttpClient to Get a list of Orders from REST API.

Json that the httpClient receives looks like:

[
    {
        "id": 1,
        "orderTime": "2021-01-28T14:55:03.077",
        "userId": 0,
        "vat": 0,
        "products": null,
        "discount": 0,
        "shippingPrice": 0,
        "shipped": true,
        "cancelled": true,
        "cancelReason": "string"
    },
    {
        "id": 2,
        "orderTime": "2021-01-28T14:55:03.077",
        "userId": 2,
        "vat": 0,
        "products": null,
        "discount": 10,
        "shippingPrice": 0,
        "shipped": false,
        "cancelled": false,
        "cancelReason": null
    }
]

And for deserialization I am using JsonSerializer:

var returnOrders = await JsonSerializer.DeserializeAsync<List<Order>>(await response.Content.ReadAsStreamAsync());

From that I do get the correct amount of objects on List, but all of them have values of 0 or null etc. What am I doing wrong?

Before I was using ReadAsAsync() which worked fine, but is deprecated in .Net core 3

await response.Content.ReadAsAsync<List<Object>>();
7
  • Have you checked the query you fire whether the Order.Products has value? I mean does your query Includes the mapped entities there? Is your data correct, I mean should be data there? Commented Jan 29, 2021 at 12:15
  • The Products are null on the database, do thats fine. But For example ID on all the objects is 0, which is not the case in the Json Commented Jan 29, 2021 at 12:24
  • So if you want different default value for Order.Products than null when there is no data there in the database then I would initiate Order.Products field int he constructor. As a result it will be a list having zero element. Is this what you are looking for? Commented Jan 29, 2021 at 12:26
  • 1
    I think you might have misunderstood my issue here. The object I get from the deserialisation is different than the one in Json and Db. And it goes for the object or Order not specifically Order.Products Commented Jan 29, 2021 at 12:34
  • You need to make sure, that the spelling of your properties is the same as in the json file. If you want to use different spelling, then you have to use attributes to tell the json deserializer which property is which field in the json Commented Jan 29, 2021 at 12:40

2 Answers 2

6

By default JsonSerializer look for properties in json with the same name as the one defined in your class. In your case you are using CamelCase naming convention, so you need to specify it like this:

var options = new JsonSerializerOptions()
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
var returnOrders = await JsonSerializer.DeserializeAsync<List<Order>>(await response.Content.ReadAsStreamAsync(), options);
Sign up to request clarification or add additional context in comments.

Comments

0

This might happen due to JSON deserialization conventions used by different deserialisers. For instance some time the case of JSON keys matter.

Try using NewtonsoftJSON deserialiser instead of the default one your are using. It'll parse JSON without checking the case.

string json = @"{
'Email': '[email protected]',
'Active': true,
'CreatedDate': '2013-01-20T00:00:00Z',
'Roles': [ 'User', 'Admin' ]
}";

Account account = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine(account.Email);

2 Comments

Well, I have the same class for Frontend and Backend and they both use the same Serializer in System.Text.Json. If I use NewtonsoftJson that is used by Microsoft.AspNet.WebApi.Client it works fine. I see no reason why it wouldn't deserialized with System.Text.Json when it was serialized with it.
I got your point and you are completely right. However the point I'm trying to make is the way different deserialiser handles the JSON parsing. I've faced not same although similar issue an year back and resolved by switching my JSON parser. @Snackerino

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.