Project Introduction
The Quiz Management System is designed to facilitate the creation, management, and evaluation of quizzes for users. Built using ASP.NET and SQL Server, this application provides a platform for users to create quizzes, answer questions, and track their performance. The system allows administrators to manage users and roles, while users can take quizzes, view their scores, and receive notifications about their achievements. This project aims to enhance the learning experience by providing an interactive and engaging way to assess knowledge.
Project Objectives
- To create a secure user authentication system for managing user accounts and roles.
- To enable users to create and manage quizzes, including adding questions and answers.
- To facilitate the answering of quiz questions and submission of answers.
- To track user scores and performance across multiple quizzes.
- To provide notifications to users regarding their quiz attempts and achievements.
- To generate reports on user performance and quiz statistics.
- To implement a system for users to earn achievements based on their quiz performance.
Project Modules
- User Management Module: Handles user registration, login, and role management.
- Quiz Management Module: Allows users to create, edit, and delete quizzes.
- Question Management Module: Facilitates the addition and management of questions within quizzes.
- Answer Management Module: Manages the answers for each question, including correct answers.
- Score Management Module: Tracks and records user scores for each quiz attempt.
- Performance Tracking Module: Analyzes user performance across quizzes and generates reports.
- Notification Module: Sends notifications to users regarding quiz results and achievements.
- Achievement Module: Manages user achievements based on quiz performance.
SQL Server Database Tables
-- Create Users Table
CREATE TABLE Users (
UserId INT PRIMARY KEY IDENTITY(1,1),
Username NVARCHAR(50) NOT NULL UNIQUE,
PasswordHash NVARCHAR(256) NOT NULL,
Email NVARCHAR(100) NOT NULL UNIQUE,
RoleId INT,
CreatedAt DATETIME DEFAULT GETDATE(),
FOREIGN KEY (RoleId) REFERENCES Roles(RoleId)
);
-- Create Roles Table
CREATE TABLE Roles (
RoleId INT PRIMARY KEY IDENTITY(1,1),
RoleName NVARCHAR(50) NOT NULL UNIQUE
);
-- Create Quizzes Table
CREATE TABLE Quizzes (
QuizId INT PRIMARY KEY IDENTITY(1,1),
Title NVARCHAR(100) NOT NULL,
Description NVARCHAR(MAX),
CreatedAt DATETIME DEFAULT GETDATE(),
CreatedBy INT,
FOREIGN KEY (CreatedBy) REFERENCES Users(UserId)
);
-- Create Questions Table
CREATE TABLE Questions (
QuestionId INT PRIMARY KEY IDENTITY(1,1),
QuizId INT,
QuestionText NVARCHAR(MAX) NOT NULL,
CreatedAt DATETIME DEFAULT GETDATE(),
FOREIGN KEY (QuizId) REFERENCES Quizzes(QuizId)
);
-- Create Answers Table
CREATE TABLE Answers (
AnswerId INT PRIMARY KEY IDENTITY(1,1),
QuestionId INT,
AnswerText NVARCHAR(MAX) NOT NULL,
IsCorrect BIT NOT NULL,
CreatedAt DATETIME DEFAULT GETDATE(),
FOREIGN KEY (QuestionId) REFERENCES Questions(QuestionId)
);
-- Create Scores Table
CREATE TABLE Scores (
ScoreId INT PRIMARY KEY IDENTITY(1,1),
UserId INT,
QuizId INT,
Score INT NOT NULL,
AttemptedAt DATETIME DEFAULT GETDATE(),
FOREIGN KEY (User Id) REFERENCES Users(UserId),
FOREIGN KEY (QuizId) REFERENCES Quizzes(QuizId)
);
-- Create Performance Table
CREATE TABLE Performance (
PerformanceId INT PRIMARY KEY IDENTITY(1,1),
UserId INT,
TotalQuizzes INT NOT NULL,
TotalScore INT NOT NULL,
AverageScore DECIMAL(5, 2) NOT NULL,
CreatedAt DATETIME DEFAULT GETDATE(),
FOREIGN KEY (User Id) REFERENCES Users(UserId)
);
-- Create Notifications Table
CREATE TABLE Notifications (
NotificationId INT PRIMARY KEY IDENTITY(1,1),
UserId INT,
Message NVARCHAR(256) NOT NULL,
IsRead BIT DEFAULT 0,
CreatedAt DATETIME DEFAULT GETDATE(),
FOREIGN KEY (User Id) REFERENCES Users(UserId)
);
-- Create Achievements Table
CREATE TABLE Achievements (
AchievementId INT PRIMARY KEY IDENTITY(1,1),
UserId INT,
Title NVARCHAR(100) NOT NULL,
Description NVARCHAR(MAX),
CreatedAt DATETIME DEFAULT GETDATE(),
FOREIGN KEY (User Id) REFERENCES Users(UserId)
);
Explanation of the Tables
Users: Stores user information, including username, password hash, email, and role.
Roles: Defines user roles (e.g., Admin, User).
Quizzes: Contains quiz details, including title, description, creation date, and creator.
Questions: Stores questions associated with quizzes, including the question text and creation date.
Answers: Contains possible answers for each question, indicating which answer is correct.
Scores: Tracks user scores for each quiz attempt, including the user ID, quiz ID, score, and attempt date.
Performance: Stores performance metrics for users, including total quizzes taken, total score, and average score.
Notifications: Manages notifications for users, such as alerts for new quizzes or achievements.
Achievements: Stores achievements earned by users, including title and description.
To create a model and repository pattern using ADO.NET for the provided SQL Server tables in an ASP.NET application
We will follow these steps:
Create Models
Define C# classes that represent each table.
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
public string PasswordHash { get; set; }
public string Email { get; set; }
public int? RoleId { get; set; }
public DateTime CreatedAt { get; set; }
}
public class Role
{
public int RoleId { get; set; }
public string RoleName { get; set; }
}
public class Quiz
{
public int QuizId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime CreatedAt { get; set; }
public int CreatedBy { get; set; }
}
public class Question
{
public int QuestionId { get; set; }
public int QuizId { get; set; }
public string QuestionText { get; set; }
public DateTime CreatedAt { get; set; }
}
public class Answer
{
public int AnswerId { get; set; }
public int QuestionId { get; set; }
public string AnswerText { get; set; }
public bool IsCorrect { get; set; }
public DateTime CreatedAt { get; set; }
}
public class Score
{
public int ScoreId { get; set; }
public int UserId { get; set; }
public int QuizId { get; set; }
public int ScoreValue { get; set; }
public DateTime AttemptedAt { get; set; }
}
public class Performance
{
public int PerformanceId { get; set; }
public int UserId { get; set; }
public int TotalQuizzes { get; set; }
public int TotalScore { get; set; }
public decimal AverageScore { get; set; }
public DateTime CreatedAt { get; set; }
}
public class Notification
{
public int NotificationId { get; set; }
public int UserId { get; set; }
public string Message { get; set; }
public bool IsRead { get; set; }
public DateTime CreatedAt { get; set; }
}
public class Achievement
{
public int AchievementId { get; set; }
public int UserId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime CreatedAt { get; set; }
}
Create Repositories
Next, we will create a generic repository interface and a concrete implementation for each model. Here’s an example of how to implement the repository pattern using ADO.NET.
Generic Repository Interface
public interface IRepository<T>
{
IEnumerable<T> GetAll();
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Delete(int id);
}
User Repository Implementation
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
public class UserRepository : IRepository<User>
{
private readonly string _connectionString;
public UserRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<User> GetAll()
{
var users = new List<User>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Users", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
users.Add(new User
{
UserId = (int)reader["User Id"],
Username = reader["Username"].ToString(),
PasswordHash = reader["PasswordHash"].ToString(),
Email = reader["Email"].ToString(),
RoleId = reader["RoleId"] as int?,
CreatedAt = (DateTime)reader["CreatedAt"]
});
}
}
}
return users;
}
public User GetById(int id)
{
User user = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Users WHERE UserId = @User Id", connection);
command.Parameters.AddWithValue("@User Id", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
user = new User
{
UserId = (int)reader["User Id"],
Username = reader["Username"].ToString(),
PasswordHash = reader["PasswordHash"].ToString(),
Email = reader["Email"].ToString(),
RoleId = reader["RoleId"] as int?,
CreatedAt = (DateTime)reader["CreatedAt"]
};
}
}
}
return user;
}
public void Add(User user)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Users (Username, PasswordHash, Email, RoleId) VALUES (@Username, @PasswordHash, @Email, @RoleId)", connection);
command.Parameters.AddWithValue("@Username", user.Username);
command.Parameters.AddWithValue("@PasswordHash", user.PasswordHash);
command.Parameters.AddWithValue("@Email", user.Email);
command.Parameters.AddWithValue("@RoleId", (object)user.RoleId ?? DBNull.Value);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(User user)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Users SET Username = @Username, PasswordHash = @PasswordHash, Email = @Email, RoleId = @RoleId WHERE UserId = @User Id", connection);
command.Parameters.AddWithValue("@User Id", user.UserId);
command.Parameters.AddWithValue("@Username", user.Username);
command.Parameters.AddWithValue("@PasswordHash", user.PasswordHash);
command.Parameters.AddWithValue("@Email", user.Email);
command.Parameters.AddWithValue("@RoleId", (object)user.RoleId ?? DBNull.Value);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Users WHERE UserId = @User Id", connection);
command.Parameters.AddWithValue("@User Id", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
Other Repository Implementations
You can create similar repository classes for the other models (e.g., Role, Quiz, Question, Answer, Score, Performance, Notification, Achievement). Below is an example of how to implement the QuizRepository.
Quiz Repository Implementation
public class QuizRepository : IRepository<Quiz>
{
private readonly string _connectionString;
public QuizRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Quiz> GetAll()
{
var quizzes = new List<Quiz>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Quizzes", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
quizzes.Add(new Quiz
{
QuizId = (int)reader["QuizId"],
Title = reader["Title"].ToString(),
Description = reader["Description"].ToString(),
CreatedAt = (DateTime)reader["CreatedAt"],
CreatedBy = (int)reader["CreatedBy"]
});
}
}
}
return quizzes;
}
public Quiz GetById(int id)
{
Quiz quiz = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Quizzes WHERE QuizId = @QuizId", connection);
command.Parameters.AddWithValue("@QuizId", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
quiz = new Quiz
{
QuizId = (int) reader["QuizId"],
Title = reader["Title"].ToString(),
Description = reader["Description"].ToString(),
CreatedAt = (DateTime)reader["CreatedAt"],
CreatedBy = (int)reader["CreatedBy"]
};
}
}
}
return quiz;
}
public void Add(Quiz quiz)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Quizzes (Title, Description, CreatedBy) VALUES (@Title, @Description, @CreatedBy)", connection);
command.Parameters.AddWithValue("@Title", quiz.Title);
command.Parameters.AddWithValue("@Description", quiz.Description);
command.Parameters.AddWithValue("@CreatedBy", quiz.CreatedBy);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(Quiz quiz)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Quizzes SET Title = @Title, Description = @Description, CreatedBy = @CreatedBy WHERE QuizId = @QuizId", connection);
command.Parameters.AddWithValue("@QuizId", quiz.QuizId);
command.Parameters.AddWithValue("@Title", quiz.Title);
command.Parameters.AddWithValue("@Description", quiz.Description);
command.Parameters.AddWithValue("@CreatedBy", quiz.CreatedBy);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Quizzes WHERE QuizId = @QuizId", connection);
command.Parameters.AddWithValue("@QuizId", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
By following this pattern, you can create repositories for all the other models similarly. This approach promotes separation of concerns, making your code more maintainable and testable. Each repository handles its own data access logic, allowing for easier updates and modifications in the future.
Create all remaining repositories
Sure! Below are the implementations for the remaining repositories based on the models we defined earlier. Each repository will follow the same pattern as the User Repository and QuizRepository.
Role Repository Implementation
public class RoleRepository : IRepository<Role>
{
private readonly string _connectionString;
public RoleRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Role> GetAll()
{
var roles = new List<Role>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Roles", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
roles.Add(new Role
{
RoleId = (int)reader["RoleId"],
RoleName = reader["RoleName"].ToString()
});
}
}
}
return roles;
}
public Role GetById(int id)
{
Role role = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Roles WHERE RoleId = @RoleId", connection);
command.Parameters.AddWithValue("@RoleId", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
role = new Role
{
RoleId = (int)reader["RoleId"],
RoleName = reader["RoleName"].ToString()
};
}
}
}
return role;
}
public void Add(Role role)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Roles (RoleName) VALUES (@RoleName)", connection);
command.Parameters.AddWithValue("@RoleName", role.RoleName);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(Role role)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Roles SET RoleName = @RoleName WHERE RoleId = @RoleId", connection);
command.Parameters.AddWithValue("@RoleId", role.RoleId);
command.Parameters.AddWithValue("@RoleName", role.RoleName);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Roles WHERE RoleId = @RoleId", connection);
command.Parameters.AddWithValue("@RoleId", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
Question Repository Implementation
public class QuestionRepository : IRepository<Question>
{
private readonly string _connectionString;
public QuestionRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Question> GetAll()
{
var questions = new List<Question>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Questions", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
questions.Add(new Question
{
QuestionId = (int)reader["QuestionId"],
QuizId = (int)reader["QuizId"],
QuestionText = reader["QuestionText"].ToString(),
CreatedAt = (DateTime)reader["CreatedAt"]
});
}
}
}
return questions;
}
public Question GetById(int id)
{
Question question = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Questions WHERE QuestionId = @QuestionId", connection);
command.Parameters.AddWithValue("@QuestionId", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
question = new Question
{
QuestionId = (int)reader["QuestionId"],
QuizId = (int)reader["QuizId"],
QuestionText = reader["QuestionText"].ToString(),
CreatedAt = (DateTime)reader["CreatedAt"]
};
}
}
}
return question;
}
public void Add(Question question)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Questions (QuizId, QuestionText) VALUES (@QuizId, @QuestionText)", connection);
command.Parameters.AddWithValue("@QuizId", question.QuizId);
command.Parameters.AddWithValue("@QuestionText", question.QuestionText);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(Question question)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Questions SET QuizId = @QuizId, QuestionText = @QuestionText WHERE QuestionId = @QuestionId", connection);
command.Parameters.AddWithValue("@QuestionId", question.QuestionId);
command.Parameters.AddWithValue("@QuizId", question.QuizId);
command.Parameters.AddWithValue("@QuestionText", question.QuestionText);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Questions WHERE QuestionId = @QuestionId", connection);
command.Parameters.AddWithValue("@QuestionId", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
Answer Repository Implementation
public class AnswerRepository : IRepository<Answer>
{
private readonly string _connectionString;
public AnswerRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Answer> GetAll()
{
var answers = new List<Answer>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Answers", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
answers.Add(new Answer
{
AnswerId = (int)reader["AnswerId"],
QuestionId = (int)reader["QuestionId"],
AnswerText = reader["AnswerText"].ToString(),
IsCorrect = (bool)reader["IsCorrect"]
});
}
}
}
return answers;
}
public Answer GetById(int id)
{
Answer answer = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Answers WHERE AnswerId = @AnswerId", connection);
command.Parameters.AddWithValue("@AnswerId", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
answer = new Answer
{
AnswerId = (int)reader["AnswerId"],
QuestionId = (int)reader["QuestionId"],
AnswerText = reader["AnswerText"].ToString(),
IsCorrect = (bool)reader["IsCorrect"]
};
}
}
}
return answer;
}
public void Add(Answer answer)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Answers (QuestionId, AnswerText, IsCorrect) VALUES (@QuestionId, @AnswerText, @IsCorrect)", connection);
command.Parameters.AddWithValue("@QuestionId", answer.QuestionId);
command.Parameters.AddWithValue("@AnswerText", answer.AnswerText);
command.Parameters.AddWithValue("@IsCorrect", answer.IsCorrect);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(Answer answer)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Answers SET QuestionId = @QuestionId, AnswerText = @AnswerText, IsCorrect = @IsCorrect WHERE AnswerId = @AnswerId", connection);
command.Parameters.AddWithValue("@AnswerId", answer.AnswerId);
command.Parameters.AddWithValue("@QuestionId", answer.QuestionId);
command.Parameters.AddWithValue("@AnswerText", answer.AnswerText);
command.Parameters.AddWithValue("@IsCorrect", answer.IsCorrect);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Answers WHERE AnswerId = @AnswerId", connection);
command.Parameters.AddWithValue("@AnswerId", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
Score Repository Implementation
public class ScoreRepository : IRepository<Score>
{
private readonly string _connectionString;
public ScoreRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Score> GetAll()
{
var scores = new List<Score>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Scores", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
scores.Add(new Score
{
ScoreId = (int)reader["ScoreId"],
UserId = (int)reader ["User Id"],
QuizId = (int)reader["QuizId"],
Points = (int)reader["Points"],
CreatedAt = (DateTime)reader["CreatedAt"]
});
}
}
}
return scores;
}
public Score GetById(int id)
{
Score score = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Scores WHERE ScoreId = @ScoreId", connection);
command.Parameters.AddWithValue("@ScoreId", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
score = new Score
{
ScoreId = (int)reader["ScoreId"],
UserId = (int)reader["User Id"],
QuizId = (int)reader["QuizId"],
Points = (int)reader["Points"],
CreatedAt = (DateTime)reader["CreatedAt"]
};
}
}
}
return score;
}
public void Add(Score score)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Scores (User Id, QuizId, Points) VALUES (@User Id, @QuizId, @Points)", connection);
command.Parameters.AddWithValue("@User Id", score.UserId);
command.Parameters.AddWithValue("@QuizId", score.QuizId);
command.Parameters.AddWithValue("@Points", score.Points);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(Score score)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Scores SET UserId = @User Id, QuizId = @QuizId, Points = @Points WHERE ScoreId = @ScoreId", connection);
command.Parameters.AddWithValue("@ScoreId", score.ScoreId);
command.Parameters.AddWithValue("@User Id", score.UserId);
command.Parameters.AddWithValue("@QuizId", score.QuizId);
command.Parameters.AddWithValue("@Points", score.Points);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Scores WHERE ScoreId = @ScoreId", connection);
command.Parameters.AddWithValue("@ScoreId", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
Performance Repository Implementation
public class PerformanceRepository : IRepository<Performance>
{
private readonly string _connectionString;
public PerformanceRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Performance> GetAll()
{
var performances = new List<Performance>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Performances", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
performances.Add(new Performance
{
PerformanceId = (int)reader["PerformanceId"],
UserId = (int)reader["User Id"],
QuizId = (int)reader["QuizId"],
ScoreId = (int)reader["ScoreId"],
CreatedAt = (DateTime)reader["CreatedAt"]
});
}
}
}
return performances;
}
public Performance GetById(int id)
{
Performance performance = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Performances WHERE PerformanceId = @PerformanceId", connection);
command.Parameters.AddWithValue("@PerformanceId", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
performance = new Performance
{
PerformanceId = (int)reader["PerformanceId"],
UserId = (int)reader["User Id"],
QuizId = (int)reader["QuizId"],
ScoreId = (int)reader["ScoreId"],
CreatedAt = (DateTime)reader["CreatedAt"]
};
}
}
}
return performance;
}
public void Add(Performance performance)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Performances (User Id, QuizId, ScoreId) VALUES (@User Id, @QuizId, @ScoreId)", connection);
command.Parameters.AddWithValue("@User Id", performance.UserId);
command.Parameters.AddWithValue("@QuizId", performance.QuizId);
command.Parameters.AddWithValue("@ ScoreId", performance.ScoreId);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(Performance performance)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Performances SET UserId = @User Id, QuizId = @QuizId, ScoreId = @ScoreId WHERE PerformanceId = @PerformanceId", connection);
command.Parameters.AddWithValue("@PerformanceId", performance.PerformanceId);
command.Parameters.AddWithValue("@User Id", performance.UserId);
command.Parameters.AddWithValue("@QuizId", performance.QuizId);
command.Parameters.AddWithValue("@ScoreId", performance.ScoreId);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Performances WHERE PerformanceId = @PerformanceId", connection);
command.Parameters.AddWithValue("@PerformanceId", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
Notification Repository Implementation
public class NotificationRepository : IRepository<Notification>
{
private readonly string _connectionString;
public NotificationRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Notification> GetAll()
{
var notifications = new List<Notification>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Notifications", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
notifications.Add(new Notification
{
NotificationId = (int)reader["NotificationId"],
UserId = (int)reader["User Id"],
Message = reader["Message"].ToString(),
CreatedAt = (DateTime)reader["CreatedAt"]
});
}
}
}
return notifications;
}
public Notification GetById(int id)
{
Notification notification = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Notifications WHERE NotificationId = @NotificationId", connection);
command.Parameters.AddWithValue("@NotificationId", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
notification = new Notification
{
NotificationId = (int)reader["NotificationId"],
UserId = (int)reader["User Id"],
Message = reader["Message"].ToString(),
CreatedAt = (DateTime)reader["CreatedAt"]
};
}
}
}
return notification;
}
public void Add(Notification notification)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Notifications (User Id, Message) VALUES (@User Id, @Message)", connection);
command.Parameters.AddWithValue("@User Id", notification.UserId);
command.Parameters.AddWithValue("@Message", notification.Message);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(Notification notification)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Notifications SET UserId = @User Id, Message = @Message WHERE NotificationId = @NotificationId", connection);
command.Parameters.AddWithValue("@NotificationId", notification.NotificationId);
command.Parameters.AddWithValue("@User Id", notification.UserId);
command.Parameters.AddWithValue("@Message", notification.Message);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Notifications WHERE NotificationId = @NotificationId", connection);
command.Parameters.AddWithValue("@NotificationId", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
Achievement Repository Implementation
public class AchievementRepository : IRepository<Achievement>
{
private readonly string _connectionString;
public AchievementRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Achievement> GetAll()
{
var achievements = new List<Achievement>();
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Achievements", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
achievements.Add(new Achievement
{
AchievementId = (int)reader["AchievementId"],
UserId = (int)reader["User Id"],
Title = reader["Title"].ToString(),
Description = reader["Description"].ToString(),
CreatedAt = (DateTime)reader["CreatedAt"]
});
}
}
}
return achievements;
}
public Achievement GetById(int id)
{
Achievement achievement = null;
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("SELECT * FROM Achievements WHERE AchievementId = @AchievementId", connection);
command.Parameters.AddWithValue("@AchievementId", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
achievement = new Achievement
{
AchievementId = (int)reader["AchievementId"],
UserId = (int)reader["User Id"],
Title = reader["Title"].ToString(),
Description = reader["Description"].ToString(),
CreatedAt = (DateTime)reader["CreatedAt"]
};
}
}
}
return achievement;
}
public void Add(Achievement achievement)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("INSERT INTO Achievements (User Id, Title, Description) VALUES (@User Id, @Title, @Description)", connection);
command.Parameters.AddWithValue("@User Id", achievement.UserId);
command.Parameters.AddWithValue("@Title", achievement.Title);
command.Parameters.AddWithValue("@Description", achievement.Description);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Update(Achievement achievement)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("UPDATE Achievements SET UserId = @User Id, Title = @Title, Description = @Description WHERE AchievementId = @AchievementId", connection);
command.Parameters.AddWithValue("@AchievementId", achievement.AchievementId);
command.Parameters.AddWithValue("@User Id", achievement.UserId);
command.Parameters.AddWithValue("@Title", achievement.Title);
command.Parameters.AddWithValue("@Description", achievement.Description);
connection.Open();
command.ExecuteNonQuery();
}
}
public void Delete(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand("DELETE FROM Achievements WHERE AchievementId = @AchievementId", connection);
command.Parameters.AddWithValue("@AchievementId", id);
connection.Open();
command.ExecuteNonQuery();
}
}
}
With these implementations, you now have a complete set of repository classes for managing the various models in your application. Each repository follows a consistent pattern for CRUD operations, ensuring that your data access layer is organized and maintainable. You can further enhance these repositories by adding methods for more complex queries or business logic as needed.
To create controllers for each repository in an ASP.NET MVC application
We will follow the standard MVC pattern. Each controller will handle HTTP requests, interact with the corresponding repository, and return views or data as needed.
Below are example controllers for each of the repositories we created earlier
Each controller will include basic CRUD actions (Create, Read, Update, Delete) and will use dependency injection to access the repositories.
UserController
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
public class UserController : Controller
{
private readonly UserRepository _userRepository;
public UserController(UserRepository userRepository)
{
_userRepository = userRepository;
}
public IActionResult Index()
{
var users = _userRepository.GetAll();
return View(users);
}
public IActionResult Details(int id)
{
var user = _userRepository.GetById(id);
return View(user);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(User user)
{
if (ModelState.IsValid)
{
_userRepository.Add(user);
return RedirectToAction(nameof(Index));
}
return View(user);
}
public IActionResult Edit(int id)
{
var user = _userRepository.GetById(id);
return View(user);
}
[HttpPost]
public IActionResult Edit(User user)
{
if (ModelState.IsValid)
{
_userRepository.Update(user);
return RedirectToAction(nameof(Index));
}
return View(user);
}
public IActionResult Delete(int id)
{
var user = _userRepository.GetById(id);
return View(user);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_userRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
RoleController
using Microsoft.AspNetCore.Mvc;
public class RoleController : Controller
{
private readonly RoleRepository _roleRepository;
public RoleController(RoleRepository roleRepository)
{
_roleRepository = roleRepository;
}
public IActionResult Index()
{
var roles = _roleRepository.GetAll();
return View(roles);
}
public IActionResult Details(int id)
{
var role = _roleRepository.GetById(id);
return View(role);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Role role)
{
if (ModelState.IsValid)
{
_roleRepository.Add(role);
return RedirectToAction(nameof(Index));
}
return View(role);
}
public IActionResult Edit(int id)
{
var role = _roleRepository.GetById(id);
return View(role);
}
[HttpPost]
public IActionResult Edit(Role role)
{
if (ModelState.IsValid)
{
_roleRepository.Update(role);
return RedirectToAction(nameof(Index));
}
return View(role);
}
public IActionResult Delete(int id)
{
var role = _roleRepository.GetById(id);
return View(role);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_roleRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
QuizController
using Microsoft.AspNetCore.Mvc;
public class QuizController : Controller
{
private readonly QuizRepository _quizRepository;
public QuizController(QuizRepository quizRepository)
{
_quizRepository = quizRepository;
}
public IActionResult Index()
{
var quizzes = _quizRepository.GetAll();
return View(quizzes);
}
public IActionResult Details(int id)
{
var quiz = _quizRepository.GetById(id);
return View(quiz);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Quiz quiz)
{
if (ModelState.IsValid)
{
_quizRepository.Add(quiz);
return RedirectToAction(nameof(Index));
}
return View(quiz);
}
public IActionResult Edit(int id)
{
var quiz = _quizRepository.GetById(id);
return View(quiz);
}
[HttpPost]
public IActionResult Edit(Quiz quiz)
{
if (ModelState.IsValid)
{
_quizRepository.Update(quiz);
return RedirectToAction(nameof(Index));
}
return View(quiz);
}
public IActionResult Delete(int id)
{
var quiz = _quizRepository.GetById(id);
return View(quiz);
}
[HttpPost , ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_quizRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
QuestionController
using Microsoft.AspNetCore.Mvc;
public class QuestionController : Controller
{
private readonly QuestionRepository _questionRepository;
public QuestionController(QuestionRepository questionRepository)
{
_questionRepository = questionRepository;
}
public IActionResult Index()
{
var questions = _questionRepository.GetAll();
return View(questions);
}
public IActionResult Details(int id)
{
var question = _questionRepository.GetById(id);
return View(question);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Question question)
{
if (ModelState.IsValid)
{
_questionRepository.Add(question);
return RedirectToAction(nameof(Index));
}
return View(question);
}
public IActionResult Edit(int id)
{
var question = _questionRepository.GetById(id);
return View(question);
}
[HttpPost]
public IActionResult Edit(Question question)
{
if (ModelState.IsValid)
{
_questionRepository.Update(question);
return RedirectToAction(nameof(Index));
}
return View(question);
}
public IActionResult Delete(int id)
{
var question = _questionRepository.GetById(id);
return View(question);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_questionRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
AnswerController
using Microsoft.AspNetCore.Mvc;
public class AnswerController : Controller
{
private readonly AnswerRepository _answerRepository;
public AnswerController(AnswerRepository answerRepository)
{
_answerRepository = answerRepository;
}
public IActionResult Index()
{
var answers = _answerRepository.GetAll();
return View(answers);
}
public IActionResult Details(int id)
{
var answer = _answerRepository.GetById(id);
return View(answer);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Answer answer)
{
if (ModelState.IsValid)
{
_answerRepository.Add(answer);
return RedirectToAction(nameof(Index));
}
return View(answer);
}
public IActionResult Edit(int id)
{
var answer = _answerRepository.GetById(id);
return View(answer);
}
[HttpPost]
public IActionResult Edit(Answer answer)
{
if (ModelState.IsValid)
{
_answerRepository.Update(answer);
return RedirectToAction(nameof(Index));
}
return View(answer);
}
public IActionResult Delete(int id)
{
var answer = _answerRepository.GetById(id);
return View(answer);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_answerRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
ScoreController
using Microsoft.AspNetCore.Mvc;
public class ScoreController : Controller
{
private readonly ScoreRepository _scoreRepository;
public ScoreController(ScoreRepository scoreRepository)
{
_scoreRepository = scoreRepository;
}
public IActionResult Index()
{
var scores = _scoreRepository.GetAll();
return View(scores);
}
public IActionResult Details(int id)
{
var score = _scoreRepository.GetById(id);
return View(score);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Score score)
{
if (ModelState.IsValid)
{
_scoreRepository.Add(score);
return RedirectToAction(nameof(Index));
}
return View(score);
}
public IActionResult Edit(int id)
{
var score = _scoreRepository.GetById(id);
return View(score);
}
[HttpPost]
public IActionResult Edit(Score score)
{
if (ModelState.IsValid)
{
_scoreRepository.Update(score);
return RedirectToAction(nameof(Index));
}
return View(score);
}
public IActionResult Delete(int id)
{
var score = _scoreRepository.GetById(id);
return View(score);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_scoreRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
PerformanceController
using Microsoft.AspNetCore.Mvc;
public class PerformanceController : Controller
{
private readonly PerformanceRepository _performanceRepository;
public PerformanceController(PerformanceRepository performanceRepository)
{
_performanceRepository = performanceRepository;
}
public IActionResult Index()
{
var performances = _performanceRepository.GetAll();
return View(performances);
}
public IActionResult Details(int id)
{
var performance = _performanceRepository.GetById(id);
return View(performance);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Performance performance)
{
if (ModelState.IsValid)
{
_performanceRepository.Add(performance);
return RedirectToAction(nameof(Index));
}
return View(performance);
}
public IActionResult Edit(int id)
{
var performance = _performanceRepository.GetById(id);
return View(performance);
}
[HttpPost]
public IActionResult Edit(Performance performance)
{
if (ModelState.IsValid)
{
_performanceRepository.Update(performance);
return RedirectToAction(nameof(Index));
}
return View(performance);
}
public IActionResult Delete(int id)
{
var performance = _performanceRepository.GetById(id);
return View(performance);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_performanceRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
NotificationController
using Microsoft.AspNetCore.Mvc;
public class NotificationController : Controller
{
private readonly NotificationRepository _notificationRepository;
public NotificationController(NotificationRepository notificationRepository)
{
_notificationRepository = notificationRepository;
}
public IActionResult Index()
{
var notifications = _notificationRepository.GetAll();
return View(notifications);
}
public IActionResult Details(int id)
{
var notification = _notificationRepository.GetById(id);
return View(notification);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Notification notification)
{
if (ModelState.IsValid)
{
_notificationRepository.Add(notification);
return RedirectToAction(nameof(Index));
}
return View(notification);
}
public IActionResult Edit(int id)
{
var notification = _notificationRepository.GetById(id);
return View(notification);
}
[HttpPost]
public IActionResult Edit(Notification notification)
{
if (ModelState.IsValid)
{
_notificationRepository.Update(notification);
return RedirectToAction(nameof(Index));
}
return View(notification);
}
public IActionResult Delete(int id)
{
var notification = _notificationRepository.GetById(id);
return View(notification);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_notificationRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
AchievementController
using Microsoft.AspNetCore.Mvc;
public class AchievementController : Controller
{
private readonly AchievementRepository _achievementRepository;
public AchievementController(AchievementRepository achievementRepository)
{
_achievementRepository = achievementRepository;
}
public IActionResult Index()
{
var achievements = _achievementRepository.GetAll();
return View(achievements);
}
public IActionResult Details(int id)
{
var achievement = _achievementRepository.GetById(id);
return View(achievement);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Achievement achievement)
{
if (ModelState.IsValid)
{
_achievementRepository.Add(achievement);
return RedirectToAction(nameof(Index));
}
return View(achievement);
}
public IActionResult Edit(int id)
{
var achievement = _achievementRepository.GetById(id);
return View(achievement);
}
[HttpPost]
public IActionResult Edit(Achievement achievement)
{
if (ModelState.IsValid)
{
_achievementRepository.Update(achievement);
return RedirectToAction(nameof(Index));
}
return View(achievement);
}
public IActionResult Delete(int id)
{
var achievement = _achievementRepository.GetById(id);
return View(achievement);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_achievementRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
}
With these controllers, you now have a complete set of MVC controllers for managing the various models in your application. Each controller provides the necessary actions to create, read, update, and delete records.
Creating views for each of the controllers
Involves creating Razor view files that correspond to the actions in the controllers. Below, I will provide a basic structure for the views for each controller, including the necessary files for listing, creating, editing, and deleting records.
User Views
Views/User/Index.cshtml
@model IEnumerable<User>
<h2>Users</h2>
<a asp-action="Create">Create New User</a>
<table>
<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var user in Model)
{
<tr>
<td>@user.Username</td>
<td>@user.Email</td>
<td>
<a asp-action="Edit" asp-route-id="@user.UserId">Edit</a> |
<a asp-action="Delete" asp-route-id="@user.UserId">Delete</a> |
<a asp-action="Details" asp-route-id="@user.UserId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/User/Create.cshtml
@model User
<h2>Create User</h2>
<form asp-action="Create">
<div>
<label asp-for="Username"></label>
<input asp-for="Username" />
</div>
<div>
<label asp-for="PasswordHash"></label>
<input asp-for="PasswordHash" type="password" />
</div>
<div>
<label asp-for="Email"></label>
<input asp-for="Email" />
</div>
<div>
<label asp-for="RoleId"></label>
<input asp-for="RoleId" />
</div>
<button type="submit">Create</button>
</form>
Views/User/Edit.cshtml
@model User
<h2>Edit User</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="User Id" />
<div>
<label asp-for="Username"></label>
<input asp-for="Username" />
</div>
<div>
<label asp-for="PasswordHash"></label>
<input asp-for="PasswordHash" type="password" />
</div>
<div>
<label asp-for="Email"></label>
<input asp-for="Email" />
</div>
<div>
<label asp-for="RoleId"></label>
<input asp-for="RoleId" />
</div>
<button type="submit">Save</button>
</form>
Views/User/Delete.cshtml
@model User
<h2>Delete User</h2>
<h3>Are you sure you want to delete this user?</h3>
<div>
<h4>@Model.Username</h4>
<p>Email: @Model.Email</p>
</div>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="User Id" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/User/Details.cshtml
@model User
<h2>User Details</h2>
<div>
<h4>@Model.Username</h4>
<p>Email: @Model.Email</p>
<p>Role ID: @Model.RoleId</p>
<p>Created At: @Model.CreatedAt</p>
</div>
<a asp-action="Edit" asp-route-id="@Model.UserId">Edit</a> |
<a asp-action="Index">Back to List</a>
Role Views
Views/Role/Index.cshtml
@model IEnumerable<Role>
<h2>Roles</h2>
<a asp-action="Create">Create New Role</a>
<table>
<thead>
<tr>
<th>Role Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var role in Model)
{
<tr>
<td>@role.RoleName</td>
<td>
<a asp-action="Edit" asp-route-id="@role.RoleId">Edit</a> |
<a asp-action="Delete" asp-route-id="@role.RoleId">Delete</a> |
<a asp-action="Details" asp-route-id="@role.RoleId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/Role/Create.cshtml
@model Role
<h2>Create Role</h2>
<form asp-action="Create">
<div>
<label asp-for="RoleName"></label>
<input asp-for="RoleName" />
</div>
<button type="submit">Create</button>
</form>
Views/Role/Edit.cshtml
@model Role
<h2>Edit Role</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="RoleId" />
<div>
<label asp-for="RoleName"></label>
<input asp-for="RoleName" />
</div>
<button type="submit">Save</button>
</form>
Views/Role/Delete.cshtml
@model Role
<h2>Delete Role</h2>
<h3>Are you sure you want to delete this role?</h3>
<div>
<h4>@Model.RoleName</h4>
</div>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="RoleId" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/Role/Details.cshtml
@model Role
<h2>Role Details</h2>
<div>
<h4>@Model.RoleName</h4>
</div>
<a asp-action="Edit" asp-route-id="@Model.RoleId">Edit</a> |
<a asp-action="Index">Back to List</a>
Quiz Views
Views/Quiz/Index.cshtml
@model IEnumerable<Quiz>
<h2>Quizzes</h2>
<a asp-action="Create">Create New Quiz</a>
<table>
<thead>
<tr>
<th>Quiz Title</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var quiz in Model)
{
<tr>
<td>@quiz.Title</td>
<td>
<a asp-action="Edit" asp-route-id="@quiz.QuizId">Edit</a> |
<a asp-action="Delete" asp-route-id="@quiz.QuizId">Delete</a> |
<a asp-action="Details" asp-route-id="@quiz.QuizId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/Quiz/Create.cshtml
@model Quiz
<h2>Create Quiz</h2>
<form asp-action="Create">
<div>
<label asp-for="Title"></label>
<input asp-for="Title" />
</div>
<button type="submit">Create</button>
</form>
Views/Quiz/Edit.cshtml
@model Quiz
<h2>Edit Quiz</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="QuizId" />
<div>
<label asp-for="Title"></label>
<input asp-for="Title" />
</div>
<button type="submit">Save</button>
</form>
Views/Quiz/Delete.cshtml
@model Quiz
<h2>Delete Quiz</h2>
<h3>Are you sure you want to delete this quiz?</h3>
<div>
<h4>@Model.Title</h4>
</div>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="QuizId" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/Quiz/Details.cshtml
@model Quiz
<h2>Quiz Details</h2>
<div>
<h4>@Model.Title</h4>
</div>
<a asp-action="Edit" asp-route-id="@Model.QuizId">Edit</a> |
<a asp-action="Index">Back to List</a>
Question Views
Views/Question/Index.cshtml
@model IEnumerable<Question>
<h2>Questions</h2>
<a asp-action="Create">Create New Question</a>
<table>
<thead>
<tr>
<th>Question Text</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var question in Model)
{
<tr>
<td>@question.Text</td>
<td>
<a asp-action="Edit" asp-route-id="@question.QuestionId">Edit</a> |
<a asp-action="Delete" asp-route-id="@question.QuestionId">Delete</a> |
<a asp-action ="Details" asp-route-id="@question.QuestionId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/Question/Create.cshtml
@model Question
<h2>Create Question</h2>
<form asp-action="Create">
<div>
<label asp-for="Text"></label>
<input asp-for="Text" />
</div>
<div>
<label asp-for="QuizId"></label>
<input asp-for="QuizId" />
</div>
<button type="submit">Create</button>
</form>
Views/Question/Edit.cshtml
@model Question
<h2>Edit Question</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="QuestionId" />
<div>
<label asp-for="Text"></label>
<input asp-for="Text" />
</div>
<div>
<label asp-for="QuizId"></label>
<input asp-for="QuizId" />
</div>
<button type="submit">Save</button>
</form>
Views/Question/Delete.cshtml
@model Question
<h2>Delete Question</h2>
<h3>Are you sure you want to delete this question?</h3>
<div>
<h4>@Model.Text</h4>
</div>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="QuestionId" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/Question/Details.cshtml
@model Question
<h2>Question Details</h2>
<div>
<h4>@Model.Text</h4>
<p>Quiz ID: @Model.QuizId</p>
</div>
<a asp-action="Edit" asp-route-id="@Model.QuestionId">Edit</a> |
<a asp-action="Index">Back to List</a>
Answer Views
Views/Answer/Index.cshtml
@model IEnumerable<Answer>
<h2>Answers</h2>
<a asp-action="Create">Create New Answer</a>
<table>
<thead>
<tr>
<th>Answer Text</th>
<th>Question ID</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var answer in Model)
{
<tr>
<td>@answer.Text</td>
<td>@answer.QuestionId</td>
<td>
<a asp-action="Edit" asp-route-id="@answer.AnswerId">Edit</a> |
<a asp-action="Delete" asp-route-id="@answer.AnswerId">Delete</a> |
<a asp-action="Details" asp-route-id="@answer.AnswerId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/Answer/Create.cshtml
@model Answer
<h2>Create Answer</h2>
<form asp-action="Create">
<div>
<label asp-for="Text"></label>
<input asp-for="Text" />
</div>
<div>
<label asp-for="QuestionId"></label>
<input asp-for="QuestionId" />
</div>
<button type="submit">Create</button>
</form>
Views/Answer/Edit.cshtml
@model Answer
<h2>Edit Answer</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="AnswerId" />
<div>
<label asp-for="Text"></label>
<input asp-for="Text" />
</div>
<div>
<label asp-for="QuestionId"></label>
<input asp-for="QuestionId" />
</div>
<button type="submit">Save</button>
</form>
Views/Answer/Delete.cshtml
@model Answer
<h2>Delete Answer</h2>
<h3>Are you sure you want to delete this answer?</h3>
<div>
<h4>@Model.Text</h4>
</div>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="AnswerId" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/Answer/Details.cshtml
@model Answer
<h2>Answer Details</h2>
<div>
<h4>@Model.Text</h4>
<p>Question ID : @Model.QuestionId</p>
</div>
<a asp-action="Edit" asp-route-id="@Model.AnswerId">Edit</a> |
<a asp-action="Index">Back to List</a>
Score Views
Views/Score/Index.cshtml
@model IEnumerable<Score>
<h2>Scores</h2>
<a asp-action="Create">Create New Score</a>
<table>
<thead>
<tr>
<th>User ID</th>
<th>Quiz ID</th>
<th>Score Value</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var score in Model)
{
<tr>
<td>@score.UserId</td>
<td>@score.QuizId</td>
<td>@score.Value</td>
<td>
<a asp-action="Edit" asp-route-id="@score.ScoreId">Edit</a> |
<a asp-action="Delete" asp-route-id="@score.ScoreId">Delete</a> |
<a asp-action="Details" asp-route-id="@score.ScoreId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/Score/Create.cshtml
@model Score
<h2>Create Score</h2>
<form asp-action="Create">
<div>
<label asp-for="User Id"></label>
<input asp-for="User Id" />
</div>
<div>
<label asp-for="QuizId"></label>
<input asp-for="QuizId" />
</div>
<div>
<label asp-for="Value"></label>
<input asp-for="Value" />
</div>
<button type="submit">Create</button>
</form>
Views/Score/Edit.cshtml
@model Score
<h2>Edit Score</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="ScoreId" />
<div>
<label asp-for="User Id"></label>
<input asp-for="User Id" />
</div>
<div>
<label asp-for="QuizId"></label>
<input asp-for="QuizId" />
</div>
<div>
<label asp-for="Value"></label>
<input asp-for="Value" />
</div>
<button type="submit">Save</button>
</form>
Views/Score/Delete.cshtml
@model Score
<h2>Delete Score</h2>
<h3>Are you sure you want to delete this score?</h3>
<div>
<h4>User ID: @Model.UserId</h4>
<h4>Quiz ID: @Model.QuizId</h4>
<h4>Score Value: @Model.Value</h4>
</div>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="ScoreId" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/Score/Details.cshtml
@model Score
<h2>Score Details</h2>
<div>
<h4>User ID: @Model.UserId</h4>
<h4>Quiz ID: @Model.QuizId</h4>
<h4>Score Value: @Model.Value</h4>
</div>
<a asp-action="Edit" asp-route-id="@Model.ScoreId">Edit</a> |
<a asp-action="Index">Back to List</a>
Performance Views
Views/Performance/Index.cshtml
@model IEnumerable<Performance>
<h2>Performances</h2>
<a asp-action="Create">Create New Performance</a>
<table>
<thead>
<tr>
<th>User ID</th>
<th>Quiz ID</th>
<th>Performance Value</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var performance in Model)
{
<tr>
<td>@performance.UserId</td>
<td>@performance.QuizId</td>
<td>@performance.Value</td>
<td>
<a asp-action="Edit" asp-route-id="@performance.PerformanceId">Edit</a> |
<a asp-action="Delete" asp-route-id="@performance.PerformanceId">Delete</a> |
<a asp-action="Details" asp-route-id="@performance.PerformanceId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/Performance/Create.cshtml
@model Performance
<h2>Create Performance</h2>
<form asp-action="Create">
<div>
<label asp-for="User Id"></label>
<input asp-for="User Id" />
</div>
<div>
<label asp-for="QuizId"></label>
<input asp-for="QuizId" />
</div>
<div>
<label asp-for="Value"></label>
<input asp-for="Value" />
</div>
<button type="submit">Create</button>
</form>
Views/Performance/Edit.cshtml
@model Performance
<h2>Edit Performance</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="PerformanceId" />
<div>
<label asp-for="User Id"></label>
<input asp-for="User Id" />
</div>
<div>
<label asp-for="QuizId"></label>
<input asp-for="QuizId" />
</div>
<div>
<label asp-for="Value"></label>
<input asp-for="Value" />
</div>
<button type="submit">Save</button>
</form>
Views/Performance/Delete.cshtml
@model Performance
<h2>Delete Performance</h2>
<h3>Are you sure you want to delete this performance?</h3>
<div>
<h4>User ID: @Model.UserId</h4>
<h4>Quiz ID: @Model.QuizId</h4>
<h4>Performance Value: @Model.Value</h4>
</div>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="PerformanceId" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/Performance/Details.cshtml
@model Performance
<h2>Performance Details</h2>
<div>
<h4>User ID: @Model.UserId</h4>
<h4>Quiz ID: @Model.QuizId</h4>
<h4>Performance Value: @Model.Value</h4>
</div>
<a asp-action="Edit" asp-route-id="@Model.PerformanceId">Edit</a> |
<a asp-action="Index">Back to List</a>
Notification Views
Views/Notification/Index.cshtml
@model IEnumerable<Notification>
<h2>Notifications</h2>
<a asp-action="Create">Create New Notification</a>
<table>
<thead>
<tr>
<th>Message</th>
<th>User ID</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var notification in Model)
{
<tr>
<td>@notification.Message</td>
<td>@notification.UserId</td>
<td>
<a asp-action="Edit" asp-route-id="@notification.NotificationId">Edit</a> |
<a asp-action="Delete" asp-route-id="@notification.NotificationId">Delete</a> |
<a asp-action="Details" asp-route-id="@notification.NotificationId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/Notification/Create.cshtml
@model Notification
<h2>Create Notification</h2>
<form asp-action="Create">
<div>
<label asp-for="Message"></label>
<input asp-for="Message" />
</div>
<div>
<label asp-for="User Id"></label>
<input asp-for="User Id" />
</div>
<button type="submit">Create</button>
</form>
Views/Notification/Edit.cshtml
@model Notification
<h2>Edit Notification</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="NotificationId" />
<div>
<label asp-for="Message"></label>
<input asp-for="Message" />
</div>
<div>
<label asp-for="User Id"></label>
<input asp-for="User Id" />
</div>
<button type="submit">Save</button>
</form>
Views/Notification/Delete.cshtml
@model Notification
<h2>Delete Notification</h2>
<h3>Are you sure you want to delete this notification?</h3>
<div>
<h4>@Model.Message</h4>
</div>
<form asp-action="Delete Confirmed">
<input type="hidden" asp-for="NotificationId" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/Notification/Details.cshtml
@model Notification
<h2>Notification Details</h2>
<div>
<h4>Message: @Model.Message</h4>
<p>User ID: @Model.UserId</p>
</div>
<a asp-action="Edit" asp-route-id="@Model.NotificationId">Edit</a> |
<a asp-action="Index">Back to List</a>
Achievement Views
Views/Achievement/Index.cshtml
@model IEnumerable<Achievement>
<h2>Achievements</h2>
<a asp-action="Create">Create New Achievement</a>
<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var achievement in Model)
{
<tr>
<td>@achievement.Title</td>
<td>@achievement.Description</td>
<td>
<a asp-action="Edit" asp-route-id="@achievement.AchievementId">Edit</a> |
<a asp-action="Delete" asp-route-id="@achievement.AchievementId">Delete</a> |
<a asp-action="Details" asp-route-id="@achievement.AchievementId">Details</a>
</td>
</tr>
}
</tbody>
</table>
Views/Achievement/Create.cshtml
@model Achievement
<h2>Create Achievement</h2>
<form asp-action="Create">
<div>
<label asp-for="Title"></label>
<input asp-for="Title" />
</div>
<div>
<label asp-for="Description"></label>
<input asp-for="Description" />
</div>
<button type="submit">Create</button>
</form>
Views/Achievement/Edit.cshtml
@model Achievement
<h2>Edit Achievement</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="AchievementId" />
<div>
<label asp-for="Title"></label>
<input asp-for="Title" />
</div>
<div>
<label asp-for="Description"></label>
<input asp-for="Description" />
</div>
<button type="submit">Save</button>
</form>
Views/Achievement/Delete.cshtml
@model Achievement
<h2>Delete Achievement</h2>
<h3>Are you sure you want to delete this achievement?</h3>
<div>
<h4>Title: @Model.Title</h4>
<p>Description: @Model.Description</p>
</div>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="AchievementId" />
<button type="submit">Delete</button>
<a asp-action="Index">Cancel</a>
</form>
Views/Achievement/Details.cshtml
@model Achievement
<h2>Achievement Details</h2>
<div>
<h4>Title: @Model.Title</h4>
<p>Description: @Model.Description</p>
</div>
<a asp-action="Edit" asp-route-id="@Model.AchievementId">Edit</a> |
<a asp-action="Index">Back to List</a>
With these views created for each controller, you now have a complete set of Razor views that correspond to the actions in your controllers. Each view provides a user interface for managing the respective entities, allowing users to create, read, update, and delete records as needed.
Creating a dashboard page to display consolidated data related to your project
Involves aggregating information from various models and presenting it in a user-friendly format. Below, I will outline how to create a simple dashboard page in an ASP.NET MVC application, including the necessary controller action and the corresponding view.
Dashboard Controller
First, create a new controller called DashboardController. This controller will fetch data from the various repositories and pass it to the view.
Controllers/DashboardController.cs
using Microsoft.AspNetCore.Mvc;
using System.Linq;
public class DashboardController : Controller
{
private readonly UserRepository _userRepository;
private readonly RoleRepository _roleRepository;
private readonly QuizRepository _quizRepository;
private readonly QuestionRepository _questionRepository;
private readonly AnswerRepository _answerRepository;
private readonly ScoreRepository _scoreRepository;
private readonly PerformanceRepository _performanceRepository;
private readonly NotificationRepository _notificationRepository;
private readonly AchievementRepository _achievementRepository;
public DashboardController(
UserRepository userRepository,
RoleRepository roleRepository,
QuizRepository quizRepository,
QuestionRepository questionRepository,
AnswerRepository answerRepository,
ScoreRepository scoreRepository,
PerformanceRepository performanceRepository,
NotificationRepository notificationRepository,
AchievementRepository achievementRepository)
{
_userRepository = userRepository;
_roleRepository = roleRepository;
_quizRepository = quizRepository;
_questionRepository = questionRepository;
_answerRepository = answerRepository;
_scoreRepository = scoreRepository;
_performanceRepository = performanceRepository;
_notificationRepository = notificationRepository;
_achievementRepository = achievementRepository;
}
public IActionResult Index()
{
var userCount = _userRepository.GetAll().Count();
var roleCount = _roleRepository.GetAll().Count();
var quizCount = _quizRepository.GetAll().Count();
var questionCount = _questionRepository.GetAll().Count();
var answerCount = _answerRepository.GetAll().Count();
var scoreCount = _scoreRepository.GetAll().Count();
var performanceCount = _performanceRepository.GetAll().Count();
var notificationCount = _notificationRepository.GetAll().Count();
var achievementCount = _achievementRepository.GetAll().Count();
var dashboardData = new DashboardViewModel
{
UserCount = userCount,
RoleCount = roleCount,
QuizCount = quizCount,
QuestionCount = questionCount,
AnswerCount = answerCount,
ScoreCount = scoreCount,
PerformanceCount = performanceCount,
NotificationCount = notificationCount,
AchievementCount = achievementCount
};
return View(dashboardData);
}
}
Dashboard ViewModel
Create a ViewModel to hold the consolidated data for the dashboard.
Models/DashboardViewModel.cs
public class DashboardViewModel
{
public int UserCount { get; set; }
public int RoleCount { get; set; }
public int QuizCount { get; set; }
public int QuestionCount { get; set; }
public int AnswerCount { get; set; }
public int ScoreCount { get; set; }
public int PerformanceCount { get; set; }
public int NotificationCount { get; set; }
public int AchievementCount { get; set; }
}
Dashboard View
Create a view to display the dashboard data. This view will present the consolidated information in a user-friendly format.
Views/Dashboard/Index.cshtml
@model DashboardViewModel
<h2>Dashboard</h2>
<div class="dashboard">
<div class="card">
<h3>Total Users</h3>
<p>@Model.UserCount</p>
</div>
<div class="card">
<h3>Total Roles</h3>
<p>@Model.RoleCount</p>
</div>
<div class="card">
<h3>Total Quizzes</h3>
<p>@Model.QuizCount</p>
</div>
<div class="card">
<h3>Total Questions</h3>
<p>@Model.QuestionCount</p>
</div>
<div class="card">
<h3>Total Answers</h3>
<p>@Model.AnswerCount</p>
</div>
<div class="card">
<h3>Total Scores</h3>
<p>@Model.ScoreCount</p>
</div>
<div class="card">
<h3>Total Performances</h3>
<p>@Model.PerformanceCount</p>
</div>
<div class="card">
<h3>Total Notifications</h3>
<p>@Model.NotificationCount</p>
</div>
<div class="card">
<h3>Total Achievements</h3>
<p>@Model.AchievementCount</p>
</div>
</div>
<style>
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 20px;
}
.card {
border: 1px solid #ccc;
border-radius: 8px;
padding: 20px;
text-align: center;
background-color: #f9f9f9;
}
</style>
Routing
Ensure that the routing is set up to access the dashboard. You can add a route in your Startup.cs or Program.cs file to point to the dashboard.
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "dashboard",
pattern: "Dashboard",
defaults: new { controller = "Dashboard", action = "Index" });
});