0

I am trying to get a list whose type is a model(called ItemDetail). However, I get this error: "Object reference not set to an instance of an object."

public class ItemDetail
{

    public decimal sum { get; set; }
    public string username { get; set; }
    public string units { get; set; }
    public string remarks { get; set; }
}

The API code is as follows:

    [HttpGet]
    [Route("api/items/details/{id}")]
    public IEnumerable<ItemDetail> ItemDetails(int id)
    {
        using (ShopEntities entities = new ShopEntities())
        {                
            var itemDetails = entities.vwItemDetails.ToList();

            var userIds = from data in itemDetails
                         select data.Userid;

            var item_Details = new List<ItemDetail> ();                

            foreach (int userId in userIds)
            {
                int totals = (int)entities.vwItemDetails
                    .Where(i => i.UserID == userId & i.item_id == id)
                    .Select(i => i.quantity)
                    .DefaultIfEmpty(0)
                    .Sum();


                var itemRecord = entities.vwItemDetails.SingleOrDefault(i => i.item_id == id & i.Userid == userId);
                item_Details.Append(new ItemDetail
                {
                    username = itemRecord.username,
                    units = itemRecord.units,
                    remarks = itemRecord.Remarks,
                    sum = totals
                    
                });

            }

            return item_Details;


        }
    }

Thanks in advance for your help.

EDIT: The error occurs inside the foreach loop where I'm trying to append the new ItemDetail (item_Details.Append(new ItemDetail)

4
  • 1
    Can you indicate on what line you experience the error? Commented Oct 16, 2020 at 18:43
  • Ok @Logarr Indicated in the EDIT part at the end Commented Oct 16, 2020 at 19:01
  • 1
    var itemRecord = entities.vwItemDetails.SingleOrDefault(...) here you allow itemDetail to be null yet you don't check for this case afterwards. Commented Oct 16, 2020 at 19:24
  • 1
    Also, exact text of the exception would be helpful. Commented Oct 16, 2020 at 19:25

1 Answer 1

2

I think I see the problem...

var itemRecord = entities.vwItemDetails.SingleOrDefault(i => i.item_id == id & i.Userid == userId);

Your filtering for the SingleOrDefault() is using a bitwise AND operator instead of boolean one. The value of itemRecord as it's written right now is almost certainly always null. Try changing that line to this:

var itemRecord = entities.vwItemDetails.SingleOrDefault(i => i.item_id == id && i.Userid == userId);

EDIT:

I just realized you do the same thing in this LINQ area:

int totals = (int)entities.vwItemDetails
                .Where(i => i.UserID == userId & i.item_id == id)
                .Select(i => i.quantity)
                .DefaultIfEmpty(0)
                .Sum();

Again, totals is probably coming up as 0.

EDIT 2: There is more wrong here than I original anticipated. I created a semi-complete working sample and you've got problems beyond the use of the bitwise operator.

As orhtej2 pointed out in the comments, you are setting yourself up to return null, but you don't check for it. So that is the immediate cause of your exception. You're probably iterating through a list of user IDs where some of the IDs aren't linked to the item ID you're working with. That will return a null because of SingleOrDefault.

The fix for that is to check if itemRecord is null, and if so, do continue; to move onto the next user ID. Or if you want to stop processing and return an error, do that. Either way the situation should be handled.

Related to that is another consequence of using SingleOrDefault. A friend of mine pointed out that if you end up with more than one result in your where clause there, you will get an exception as well. Unless you can guarantee that no single user ID will have more than one instance of a given item ID in that collection of item details, you need to use a different method. The most straightforward would be to use Where() instead, and handle the IEnumerable<> that it returns. You'll have another loop, but that's showbiz.

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

1 Comment

The error persists at line "item_Details.Append(new ItemDetail"

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.