I am creating a CMS where I am displaying the information from a database. It is a school database. I have one page(View - List) on which there is a list of teachers. When user clicks on one teacher, they are directed to another page (view - show) which should have information about that particular teacher. Now, the problem is that List page is getting the data and displaying it, but the Show page is not getting any data and not giving any error. It's just that the data is not displayed.
This is my code - List.cshtml
:
@model IEnumerable<Cumulative.Models.Teacher>
<h1>This page shows the list of all the teachers.</h1>
@foreach(Cumulative.Models.Teacher CurrentTeacher in Model)
{
<div><a href="/TeacherPage/Show/@CurrentTeacher.TeacherId">@CurrentTeacher.TeacherFName @CurrentTeacher.TeacherLName</a></div>
}
Show.cshtml
:
@model Cumulative.Models.Teacher
<h1>@Model.TeacherFName @Model.TeacherLName</h1>
TeacherPageController
:
using Microsoft.AspNetCore.Mvc;
using Cumulative.Models;
using Cumulative.Controllers;
using Google.Protobuf.WellKnownTypes;
namespace Cumulative.Controllers
{
public class TeacherPageController : Controller
{
private readonly TeacherAPIController _api;
public TeacherPageController(TeacherAPIController api)
{
_api = api;
}
// TeacherPage/List -> A webpage that shows all teachers in the database
public IActionResult List()
{
// creating a variable for the list of teachers
List<Teacher> Teachers = _api.ListTeachers();
// direct us to the /Views/TeacherPage/List.cshtml
return View(Teachers);
}
// GET : TeacherPage/Show/{id} -> A webpage that shows a particular teacher in the database matching the given id
[HttpGet]
public IActionResult Show(int TeacherId)
{
// Creating a Teacher instance for the teacher information received upon inserting the id
Teacher SelectedTeacher = _api.GiveTeacherInfo(TeacherId);
return View(SelectedTeacher);
}
}
}
TeacherAPIController
:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Cumulative.Models;
using System;
using MySql.Data.MySqlClient;
namespace Cumulative.Controllers
{
[Route("api/Teacher")]
[ApiController]
public class TeacherAPIController : ControllerBase
{
private readonly SchoolDbContext _context;
// dependency injection of database context
public TeacherAPIController(SchoolDbContext context)
{
_context = context;
}
/// <summary>
/// Returns information about all the teachers
/// </summary>
/// <example>
/// GET api/teacher/GiveTeachersList -> ["","","","",""]
/// </example>
/// <returns>
/// A list of the teachers
/// </returns>
///
[HttpGet]
[Route(template:"ListTeachers")]
public List<Teacher> ListTeachers()
{
// Create a list of instances of Teachers
List<Teacher> Teachers = new List<Teacher>();
// 'using' will close the connection after the code executes
using (MySqlConnection Connection = _context.AccessDatabase())
{
Connection.Open();
// Establish a new command (query) for our database
MySqlCommand Command = Connection.CreateCommand();
//SQL query
Command.CommandText = "SELECT * FROM teachers";
// Gather Result Set of Query into a variable
using (MySqlDataReader ResultSet = Command.ExecuteReader())
{
//Loop Through Each Row of the Result Set
while (ResultSet.Read())
{
int Id = Convert.ToInt32(ResultSet["teacherid"]);
string LastName = ResultSet["teacherlname"].ToString();
string EmployeeNumber = ResultSet["employeenumber"].ToString();
DateTime HireDate = Convert.ToDateTime(ResultSet["hiredate"]);
Decimal Salary = Convert.ToDecimal(ResultSet["salary"]);
// Add the Teacher Data to the Teachers
Teacher CurrentTeacher = new Teacher()
{
TeacherId = Id,
TeacherFName = ResultSet["teacherfname"].ToString(),
TeacherLName = LastName,
EmployeeNumber = EmployeeNumber,
HireDate = HireDate,
Salary = Salary
};
Teachers.Add(CurrentTeacher);
}
}
}
return Teachers;
}
/// <summary>
/// Receives a teacher id and returns the associated teacher information
/// </summary>
/// <param name="TeacherId">The primary key of the teachers table.</param>
/// <example>
/// GET api/teacher/GiveTeacherInfo/5 -> {"":"","":"","":""}
/// </example>
/// <returns>
/// All the information about one teacher
/// </returns>
[HttpGet]
[Route(template:"GiveTeacherInfo/{TeacherId}")]
public Teacher GiveTeacherInfo(int TeacherId)
{
Teacher SelectedTeacher = new Teacher();
// 'using' will close the connection after the code executes
using (MySqlConnection Connection = _context.AccessDatabase())
{
Connection.Open();
// Establish a new command (query) for our database
MySqlCommand Command = Connection.CreateCommand();
// SQL query
Command.CommandText = $"SELECT * FROM teachers WHERE teacherid = {TeacherId}";
// Gather Result Set of Query into the Teacher
using (MySqlDataReader ResultSet = Command.ExecuteReader())
{
//Loop Through Each Row of the Result Set
while (ResultSet.Read())
{
SelectedTeacher.TeacherId = Convert.ToInt32(ResultSet["teacherid"]);
SelectedTeacher.TeacherFName = ResultSet["teacherfname"].ToString();
SelectedTeacher.TeacherLName = ResultSet["teacherlname"].ToString();
SelectedTeacher.EmployeeNumber = ResultSet["employeenumber"].ToString();
SelectedTeacher.HireDate = Convert.ToDateTime(ResultSet["hiredate"]);
SelectedTeacher.Salary = Convert.ToDecimal(ResultSet["salary"]);
}
}
}
return SelectedTeacher;
}
}
}
Teacher
class:
namespace Cumulative.Models
{
public class Teacher
{
public int TeacherId { get; set; }
public string TeacherFName { get; set; }
public string TeacherLName { get; set; }
public string EmployeeNumber { get; set; }
public DateTime HireDate { get; set; }
public Decimal Salary { get; set; }
}
}
The reason why your show page is null is, your TeacherId is 0. In asp.net core MVC defaul route is like below, but your route parameter is teacherid which caused the modelbinder fail:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
I suggest you could modify your show method to below and test again.
public IActionResult Show(int id)
{
Teacher SelectedTeacher = _api.GiveTeacherInfo(id);
return View(SelectedTeacher);
}
Result: