-1

i wrote a while loop to find each person file number from a table and add it inside another class array but for some reason, it returns an Object reference not set to an instance of an object ERROR. Here is My Class

public class Person
{
    public string IDENTITY { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }    

    public class Exam[] Exams;

    public string Data { get; set; }
}

public class Exam
{
  public string IDENTITY
  public string Name
  public int Pass_Score 
  public int Score 
  public string Grade 
}

and I have a table for person and table for Exam, My Goal is to Connect each person with all the exams he has in the exam table to return it as XML file.

    [ResponseType(typeof(Person))]
    public async Task<IHttpActionResult> GetPerson(string id)
    {
        Person p = await db.Person.FindAsync(id);
        int count = db.Exam.Count();

        Exam fS = new Exam();
        int i = 0;
        while (i < count) {
            if (fS.IDENTITY.Equals(p.IDENTITY)) {
                Exam e = new Exam();
                e.IDENTITY = fS.IDENTITY;
                e.Name= fS.Name;
                e.Pass_Score = fS.Pass_Score ;
                e.Grade= fS.Grade;
                e.Score = fS.Score ;
                i++;
            };
        }
        if (p== null)
        {
            return NotFound();
        }
        return Ok(p);
    }

My Guess's the Error Comes from inside the While loop?

Ahmed Mear
  • 69
  • 8
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Dour High Arch Aug 01 '19 at 22:33
  • 1
    Your code has multiple issues that will prevent it from compiling. That said, your object NULL error looks to be coming from the line ... if(fs.IDENTITY.Equals(p.IDENTITY)) ... the fs variable is instantiated a few lines above but its properties are never set and thus are NULL. – quaabaam Aug 01 '19 at 23:05

1 Answers1

0

@Dour High Arch: This is not a query about the null ref. but where it is ocurring.

step through your code, in the GetPerson function, is p populated? Which one of the return functions is it getting to? The return NotFound() or Ok(p)?

You are creating a new exam FS then you loop through all of the exams without assigning FS or e to anything, your if statement here if (fS.IDENTITY.Equals(p.IDENTITY)) { is always false and indeed it just ads the client details to an exam which is then forgotten.

There are a lot of issues with this code:

  1. you are not using constructors inside your objects (getting null refs)
  2. You are looking for FS.Identity = p.Identity without setting FS or it's id. (possible null ref)
  3. You are not actually retrieving any exams from the database.
  4. Exam e inside the loop never gets put into anything.
  5. Using a while loop when a foreach would do (minor readability)
  6. No Try/Catch being used
  7. Way overcomplicated approach.

Below is a rough example of how I would approach it:

    [ResponseType(typeof(Person))]
    public async Task<IHttpActionResult> GetPerson(string id)
    {
        Person p = new Person();

        try {
            p = await db.Person.FindAsync(id);

            if(p == null) {
                throw new Exception("Person " + id + " not found.");
            }

            var exams = db.Exam.FindAsync(p.IDENTITY);

            if(exams != null) {
                p.Exams = new Exam[exams.Count()];
                p.Exams = exams.ToArray();
            }
        }
        catch(Exception e) {
            //log exception here, is it just a person not found or somehting else?
            return NotFound(); 
        }

        return OK(p);
    }

A foreach loop example, the above is far better, and this method acheives nothing new:

var output = new List<Exam>();
var exams = db.getallexams();

foreach(var item in exams) {
    output.Add(item);
}

p.Exams = output.ToArray();
Slipoch
  • 750
  • 10
  • 23
  • 1
    Nice, Slipoch . i had my thoughts about not constructors inside object. However, how can i approach it with foreach as you said. – Ahmed Mear Aug 01 '19 at 23:47
  • Well the above doesn't even require a loop as you are simply retrieving the data from the db that corresponds to the person identity. This may be quicker in large dbs as the SQL db may have aching and other optimisations in order to retrieve data quicker. but for a foreach loop check the edit above. – Slipoch Aug 02 '19 at 02:01
  • You may want to change your person object so it contains a list of exams rather than an array, the array will be smaller but a list is easier to manage as you can just add a new item rather than having to re-allocate the array size. I would also create some constructors to make sure these are initialised. – Slipoch Aug 02 '19 at 02:08