1

I have a class that I use to see list of Oreders

public class OrderVM
    {
        public OrderVM() { }

        public OrderVM(OrderDTO row)
        {
            Id = row.Id;
            ClientId = row.ClientId;
            OrderDate = row.OrderDate;
        }

        public int Id { get; set; }
        public string ClientId { get; set; }
        public string OrderDate { get; set; }
        public string ClientName { get; set; }
        public string ClientSurname { get; set; }

    }

the result I want to see this in my View:

  Name    Surname      Brand          Mark
-------   --------  ------------    --------
Alexey     Petrov      Jamis         Trail
                       Scott         SPark
                     Mongoose        Expert

I decided to add a List to the class OrderVM so every client will have a List of purchased products:

    public class OrderVM
        {
            public OrderVM() { }

            public OrderVM(OrderDTO row)
            {
                Id = row.Id;
                ClientId = row.ClientId;
                OrderDate = row.OrderDate;
                Bicycles = new List<BicycleVM>();
            }

            public int Id { get; set; }
            public string ClientId { get; set; }
            public string OrderDate { get; set; }
            public string ClientName { get; set; }
            public string ClientSurname { get; set; }

            public List<BicycleVM> Bicycles { get; set; }

        }

public class BicycleVM
{
        public int Id { get; set; }
        public string Category { get; set; }
        public int CategoryId { get; set; }
        public string BrandName { get; set; }
        public string Mark { get; set; }
        public int Year { get; set; }
        public string Color { get; set; }
        public decimal WheelSize { get; set; }
        public string Frame { get; set; }
        public int Speeds { get; set; }
        public string Brake { get; set; }
        public string BicycleType { get; set; }
        public decimal Weight { get; set; }
        public decimal Price { get; set; }
        public string PriceFormatted { get; set; }
        [DisplayName("Image")]
        public string ImageName { get; set; }

        public IEnumerable<SelectListItem> Categories { get; set; }
        public IEnumerable<string> GalleryImages { get; set; }
}

now all seems good. Now I need to populate this List. To do this I did a list with data:

var orderedItems = db.Bicycles.ToArray().Where(x => listOfProductsIds.Contains(x.Id)).Select(x => new BicycleVM(x)).ToList();

inside the list 4 items with values: orderedItems

if I do the following:

OrderVM order = new OrderVM();
order.Bicycles.AddRange( new List<BicycleVM>(orderedItems));

I'm getting exeption Object reference not set to an instance of an object

I see that some Values like Categories, Category, GalleryImages are null For me it's Ok because I only need BrandName, Mark and Price.

What options do I have to avoid this exeption?

What I'm thinking about is:

orderedItems.ForEach(x => x.Categories = " ");
orderedItems.ForEach(x => x.Category = " ");
orderedItems.ForEach(x => x.GalleryImages = " ");
orderedItems.ForEach(x => x.PriceFormatted = " ");

P.s. I have read this article What is a NullReferenceException, and how do I fix it? and not sure how correct use this information for my case

  • 2
    You are only doing `Bicycles = new List();` in the constructor `OrderVM(OrderDTO row)` yet you are using the constructor `OrderVM()` – Camilo Terevinto Jul 04 '19 at 06:19

1 Answers1

1

I think if you inspect order.Bicycles just before you run the line which errors, you'll find that will be null because you created your OrderVM object using the constructor which is empty (new OrderVM());).

Only the constructor which accepts an OrderDTO as input will create a new bicycle list. Therefore when you create your object using the other (empty) constructor, Bicycles = new List<BicycleVM>(); never gets executed and the bicycle list remains null.

And you can't execute a method such as AddRange() on a null object, which is why you get an exception.

To make it safe you need to run Bicycles = new List<BicycleVM>(); in both constructors.

Example:

public class OrderVM
{
    public OrderVM() 
   { 
        Bicycles = new List<BicycleVM>(); //add this line
    }

    public OrderVM(OrderDTO row)
    {
        Id = row.Id;
        ClientId = row.ClientId;
        OrderDate = row.OrderDate;
        Bicycles = new List<BicycleVM>();
    }
ADyson
  • 44,946
  • 12
  • 41
  • 55
  • Thank you for reply. I've edited the main post - could you check if everything is ok now? – Michael Blala Jul 04 '19 at 06:48
  • Your edited version doesn't do what I suggested here. But anyway there's no need to update your question with corrected code...that makes the question and answer stop making sense if the code doesn't show a problem. Just fix it in your own code and then let me know if it helps. You need to be updating your OrderVM object, not the bicycle object...read what I've written more carefully :) – ADyson Jul 04 '19 at 06:54
  • I've read :) Could you edit the code how it should looks like, if you have time :) ? – Michael Blala Jul 04 '19 at 07:08
  • Do you understand what I mean by the "empty constructor" of your OrderVM object? You need to add one line into it, that's all. – ADyson Jul 04 '19 at 07:12
  • I updated my answer with a more detailed example. – ADyson Jul 04 '19 at 07:14
  • Thank you :) I will try your code as soon as I come home. To say the truth I haven't understood that you mean this constructors: `public OrderVM()` `public OrderVM(OrderDTO row)` :) – Michael Blala Jul 04 '19 at 07:40
  • Yes, sorry, by "empty" I mean literally the one with no code inside it! – ADyson Jul 04 '19 at 08:05
  • Your code works perfect! Thank you :) – Michael Blala Jul 04 '19 at 08:18