user1356029 user1356029 - 3 months ago 8
C# Question

Call Query Method From Loop Within View

I am relatively new to using ASP.NET MVC so forgive my ignorance if I am overlooking something simple here, but after a fair deal of research I have still found no solid solution.

I am passing a list of projects from my controller into my view of type: IEnumerable Project:

IEnumerable<Project> Projects = ViewBag.Projects;


Then looping through each project and populating a Datatable with the information. The only trouble is to get data for two of the columns in the Datatable I need to make a second DB query from within the loop.

I have created a @functions section to call a method in my repository which should return a list of archives related to any particular project:

View Top

@using stwintranet.Areas.PQP.Models
@model Year

@{
Layout = "~/Views/Shared/_Layout.cshtml";
IEnumerable<Project> Projects = ViewBag.Projects;
IEnumerable<Year> Years = ViewBag.Years;
String year = ViewBag.URLYear;
}
@functions
{
private readonly IArchive_ElectronicRepository Archive_ElectronicRepository;

public IEnumerable<Archive_Electronic> GetListArchives(int pid)
{
return Archive_ElectronicRepository.GetListArchives(pid);
}
}


View Main:

<table id="dt_basic" class="table table-striped table-bordered table-hover" width="100%">
<thead>
<tr>
<th>Project Year</th>
<th>Project Number</th>
<th>Project Title</th>
<th>Client</th>
<th>Site Address</th>
<th>Director</th>
<th>Archive Status</th>
<th>Primary Location</th>
<th>Location</th> <!-- Requires 2nd Query -->
<th>Documents</th> <!-- Requires 2nd Query -->
</tr>
</thead>
<tbody>
@foreach (var project in Projects)
{
//Get a list of archived projects
IEnumerable<Archive_Electronic> ArchiveProjects = GetListArchives(project.ProjectID);
string Docs = "";
string Locs = "";
foreach (var archive in ArchiveProjects)
{
//Write List of Docs
if (archive.DocumentType == 1)
{
Docs = Docs + "Dwg ";
}
else if (archive.DocumentType == 2)
{
Docs = Docs + "Doc ";
}
else if (archive.DocumentType == 3)
{
Docs = Docs + "Eml ";
}
//Write List of Locations
if (archive.Location == 2)
{
Locs = Locs + "Dub ";
}
else if (archive.Location == 3)
{
Locs = Locs + "Gal ";
}
else if (archive.Location == 4)
{
Locs = Locs + "Lon ";
}
else if (archive.Location == 6)
{
Locs = Locs + "Cor ";
}
}


<tr id="@project.ProjectNumber" onclick="showProject(this.id)">
<td>@project.Year</td>
<td>@project.ProjectNumber</td>
<td>@project.ProjectTitle</td>
<td>@project.Organisation.Organisation1</td>
<td>@project.SiteAddress1</td>
<td>@project.ProjectDirector</td>
<td>Archive Status will go here</td>
<td>@project.SiteArea</td>
<td>@Locs</td>
<td>@Docs</td>
</tr>

}


</tbody>
</table>


Method located within Repository:

public IEnumerable<Archive_Electronic> GetListArchives(int id)
{
return context.Archive_Electronic.Where(x => x.Project == id).DefaultIfEmpty();
}


Controller:

// GET: PQP/Stage9/ElectronicArchiveReport
public ActionResult ElectronicArchiveReport(string id)
{
ViewBag.Years = YearRepository.GetYears();
ViewBag.Projects = ProjectRepository.GetListProjects(id);
ViewBag.URLYear = id;
return View();
}


With this code as is I get a:

System.NullReferenceException: Object reference not set to an instance of an object.


for return located in view:

return Archive_ElectronicRepository.GetListArchives(pid);


located in @functions, I know you more than likely shouldn't call the DB like this which is probably why I am getting the null exception error but I am at a loss here and can't really find a proper way of doing this.

Answer

Your private readonly IArchive_ElectronicRepository Archive_ElectronicRepository; doesn't seem to be instantiated or assigned which results in the NullReferenceException