0

first of all im real beginner with c# and .net i started 10 days ago so im trying to display datas from a one-to-many relation but i have an error System.NullReferenceException : 'Object reference not set to an instance of an object.(i checked db there are datas in this table) and i dont understand why. I read many post about this but it never works, my code is almost the same than the example on the microsoft doc page but mine doesnt work.

model

        [Display(Name = "Formations")]
        public virtual ICollection<Courses> Course { get; set; }

    }

    public class Courses
    {
        [Key]
        public int CourseId { get; set; }
        [Display(Name = "Formations")]
        public string Course { get; set; }

        public virtual Users users { get; set; }
    }

Controller


       public async Task<IActionResult> Details(int? id)
       {
           if (id == null)
           {
               return NotFound();
           }

           var users = await _context.Users
               .FirstOrDefaultAsync(m => m.Id == id);
           if (users == null)
           {
               return NotFound();
           }

           return View(users);

View

            @foreach (var item in Model.Course)
                { 
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Course)
                        </td>
                    </tr>
                }
guillaume
  • 1
  • 1
  • first you need to find where the nullreference exception is comming from. And then you can check how to prevent this. Take a look here: https://stackoverflow.com/a/4660186/7968203 – Isparia Jul 29 '21 at 10:58
  • the error is coming from my loop in the view if its what you mean. – guillaume Jul 29 '21 at 11:39
  • This is possibly because the courses property is not loaded. Include the courses while searching user. `var users = await _context.Users.Include(x => x.Course) .FirstOrDefaultAsync(m => m.Id == id);` – Nitheesh Govind Jul 29 '21 at 11:47

2 Answers2

0

I asume that your model is of type User. When querying for an entity (User), related entities (Courses) are not read automatically from the database, therefore your collection is/was null.

You can change that by using Include() in your Linq query: await _context.Users.Include(u => u.Courses).FirstOrDefaultAsync(m => m.Id == id);

Just some small additional suggestions to improve your code, which helps you understand what's going on:

  • Rename your Courses class to Course since your class only represent one single course.
  • Rename the Course property to Courses since it is a collection of many objects of type Course
  • Initialize your course collection with an empty list/hash set like so public virtual public virtual ICollection<Courses> Course { get; set; } = new HashSet<Course>(); to avoid a null reference exception
  • In your view, rename item to course. "Foreach (single) course in (many) courses" is much better to read and unserstand
Random12b3
  • 159
  • 7
  • I tried to initialize my collection with an empty list when i was looking for how to fix my problem, i had not error anymore but my loop didnt display anything so i thought it was not the right thing to do. Anyway i did it with your code and everything works fine thank you very much for your help. This little project is for a job so if i get it i'll owe you one ;) – guillaume Jul 29 '21 at 14:17
  • The initialization of the collection is just to avoid a null reference exception like in your original case when a relation has not been loaded properly. An empty list resulting in showing no items is better than a program that crashes when it tries to access properties of a non exiting object. I wish you good luck with your job application! Hoping for beer as a reward :D – Random12b3 Jul 29 '21 at 14:26
0

fix the action

 var users = await _context.Users.Include(i=>i.Course)
               .FirstOrDefaultAsync(m => m.Id == id);
          

since your are usind displayfor you will have to replace foreach loop by for loop

@model User
....
@if (Model.Course!=null)
{
  @for (var i=0; i<= Model.Course.Count; i+=1)
                { 
                    <tr>
                        <td>
                            @Html.DisplayFor(model=> model.Course[i].Course)
                        </td>
                    </tr>
                }
}
Serge
  • 40,935
  • 4
  • 18
  • 45