Search code examples
c#asp.net-mvcentity-frameworkef-code-firstcode-first

Value cannot be null parameter name: source even when IEnumerable in not null


I have the following models:

public class Student
{
    public int Id { get; set; }
    [Display(Name = "First Name")]
    public string FirstName { get; set; }
    [Display(Name = "Last Name")]
    public string LastName { get; set; }
    public ICollection<WorkExperience> WorkExperiences { get; set; }
    public ICollection<Education> Educations { get; set; }
    public ICollection<Skill> Skills { get; set; }
}

public class Employer
{
    public int Id { get; set; }
    [Display(Name = "First Name")]
    public string FirstName { get; set; }
    [Display(Name = "Last Name")]
    public string LastName { get; set; }
    public ICollection<WorkExperience> WorkExperiences { get; set; }
    public ICollection<Education> Educations { get; set; }
    public ICollection<Skill> Skills { get; set; }
}

public class WorkExperience
{
    public int Id { get; set; }
    [Display(Name = "Company Name")]
    public string CompanyName { get; set; }
    [Display(Name = "Job Title")]
    public string JobTitle { get; set; }
    [Display(Name = "Experience (in years)")]
    public string Experience { get; set; }
    [Display(Description = "Enter City, Country for e.g. San Francisco, California")]
    public string Location { get; set; }
    public virtual ICollection<Employer> Employers { get; set; }
    [Display(Name = "Set as Current Company")]
    public virtual ICollection<Student> Students { get; set; }
}

I want to each student & employer to have multiple workexperiences each. So a stuent can have any number of experiences & even employer can have any number. The problem I am facing is in view where when it reaches at workexperience code it says:

Value cannot be null. Parameter name: source

However, I am getting all values in the view after passing an IEnumerable of model Student

Following is the view code

@model IEnumerable<OpenOpportunity.Models.Student>
@foreach (var student in Model)
{
    <div class="row clearfix">
        <div class="col-xs-12">
            <h1>
            @student.FirstName @student.LastName
            </h1>
        </div>
    </div>

    var count = 0;
    if (@student.WorkExperiences == null)
    {
        <small>No current position & company set</small>
        <a id="currentDetails" href="@Url.Action("EditCurrentDetails", "Main", new { area = "Students", id = student.Id })">
        <i class="fa fa-edit"></i>
        </a>
    }
    else if (@student.WorkExperiences.Count() > 0)
    {

        foreach (var work in student.WorkExperiences)
        {
            if (work.IsCurrentCompany == true)
            {
                <small>@work.JobTitle,@work.CompanyName</small>
                <a id="currentDetails" href="@Url.Action("EditCurrentDetails", "Main", new { area = "Students", id = student.Id })">
                <i class="fa fa-edit"></i>
                </a>
            }
            else
            {
                count++;
            }
        }
    }
    if (@student.WorkExperiences.Count() == count)
    {
        <small>No current position & company set</small>
        <a id="currentDetails" href="@Url.Action("EditCurrentDetails", "Main", new { area = "Students", id = student.Id })">
        <i class="fa fa-edit"></i>
        </a>
    }
}

And here is the controller code:

var userID = db.Users.Find(User.Identity.GetUserId());
                var getStudentDetails = (from x in db.Students.Include("WorkExperiences")
                                         where x.Id == userID.Student.Id
                                         select x).ToList();
                return View(getStudentDetails);

Also I would like to tell you the employer view works fine & is the view with same code. Are the relationships not properly defined? or something else?


Solution

  • Looking at your code, here's a simplified example of your flow:

    var count = 0;
    if (@student.WorkExperiences == null)
    {
        <small>No current position & company set</small>
        ...
    }
    else if (@student.WorkExperiences.Count() > 0)
    {
        foreach (var work in student.WorkExperiences)
        ...
    }
    if (@student.WorkExperiences.Count() == count)
    {
        <small>No current position & company set</small>
        ...
    }
    

    See the problem? If the WorkExperiences collection is null, then you are calling .Count() on it in the last if statement without making a null check before.

    I suppose that this last if statement is some bad leftover that you should simply remove so that your flow becomes like this:

    var count = 0;
    if (student.WorkExperiences == null || !student.WorkExperiences.Any())
    {
        <small>No current position & company set</small>
        ...
    }
    else
    {
        foreach (var work in student.WorkExperiences)
        ...
    }