user123456
user123456

Reputation: 2659

c# deserialize json to list results in null when json is empty?

I am facing this situation and it is really strange to me.

I have class A has the following

public class A
{
   public A()
   {   
      Values = new List<B>();
   }

   public virtual IList<B> Values { get; set; }
}

I have a method that will read all A records form the db.

var all = await GetAll();

here is my method

public async Task<IList<A>> GetAll(int id1)
{
    var parameters = new[]
    {
        new SqlParameter("@ProductTypeId", SqlDbType.Int) {Value = id1},  
    };

    return (await _sqlCommandWrapper.ExecuteReaderAsync("SPName", r => new  A
        {
            values = JsonConvert.DeserializeObject<IList<B>>(r["Values"].ToString())
        }, parameters)).ToList();
}

my db column r["Values"] will return json that can be deserialized to list of B class.

Then i am using linq to query all my A:

var subitems = all .Where(a=> a.Values .Count > 0).ToList();

If my r["Values"] return data, it works fine.

however if it is not then a.Values is null ?

Any reason, however I defined in my A constructor that Values = new List<B>();

Upvotes: 0

Views: 1136

Answers (1)

Mrinal Kamboj
Mrinal Kamboj

Reputation: 11478

Reason for the issue is, following code which do the Json deserialization replaces the Values of type (IList<B>), you are not doing anything with the original list that is instantiated in the constructor

values = JsonConvert.DeserializeObject<IList<B>>(r["Values"].ToString())

When r["Values"].ToString() is a valid Json it gets deserialized into IList<B> which is an assignment call, now when r["Values"].ToString() generates a Json that is a mismatch or empty then the result of the following code is Null

JsonConvert.DeserializeObject<IList<B>>(r["Values"].ToString())

In case you plan to use the List instantiated in the constructor then it should be:

Values.Add(JsonConvert.DeserializeObject<B>(r["Values"].ToString()))

In this case r["Values"].ToString() generates the Json for type B not IList<B>

However this would certainly not work as is, since you are generating a new A, which is then added to IList<A> and returned as a Task result, so that part would also need modification

Upvotes: 1

Related Questions