1

I have the following controller action to create a user.

    public ActionResult Create([Bind(Include = "Name, Email, Role, Password")] User user)
    {
        if (ModelState.IsValid)
        {
            // Create password hash
            user.Salt = Security.RandomString(16);
            user.Password = Security.Encrypt(user.Password, user.Salt);

            // Add Qualifications
            var qualification = db.Qualifications.Find(5);
            user.Qualifications.Add(qualification);

            // Apply changes
            db.Users.Add(user);
            db.SaveChanges();
        }
        return RedirectToAction("Index");
    }

It all works fine, besides the part of adding the Qualification for the user (I want to add multiple qualifications, once it works). The user model has this: public virtual ICollection<Qualification> Qualifications { get; set; } to store the qualifications (Its a many to many relationship, for which Entitiy Framework has already created a table).

I always get an error: "Object reference not set to an instance of an object.", at line: user.Qualifications.Add(qualification);

I dont understand why, after all, i did add Salt and Password properties the same way just before (and that works fine). Also I did add multiple qualifications to a user object in my seed method exactly the same way, where it also works fine.

Whats the problem here and how can i fix it?

gnj
  • 138
  • 1
  • 8
  • 1
    Hi, the User class are instantiating the Qualifications property in its constructor? It seems like that it is occuring the autobinding for the User model, and when you try to access the Qualifications property it is not instantiate. Regards, – dime2lo Jun 04 '16 at 17:58
  • If you get an NRE, first thing to do is check in the debugger what is `null`. Maybe you did, but then you should tell what you found out. – Gert Arnold Jun 04 '16 at 19:47

2 Answers2

1

This is because this qualification already exists in the database and because Qualifications is virtual. The problem you are facing is that EF is trying to create them again and add the newly created to the user.

You should create some kind of relation between the 2 objects and then assign its id's. EF will take care of the lazy loading for you.

...
db.Users.Add(user);
db.SaveChanges();

qualification.AssignedUser = user.Id;
db.Entry(qualification).State = EntityState.Modified;
await db.SaveChangesAsync();

If you do it this way you obviously can not reuse the qualification for another user and you would have to create a new one. If you don't want to do this you would do the relation the other way around.

For example:

...
user.Qualification1Id = qualification.Id;

db.Users.Add(user);
db.SaveChanges();
Florian Schaal
  • 2,586
  • 3
  • 39
  • 59
0

I fixed the issue by instantiating:

user.Qualifications = new List<Qualification>();

gnj
  • 138
  • 1
  • 8