platformslatforms asp.net mvc 5eecs.csuohio.edu/~sschung/cis408/roslytechnical...asp.net mvc 5...
TRANSCRIPT
Rosly Course Registration System Software Code walk Through by Derrick Awuah
PPPPlatformslatformslatformslatforms ASP.NET MVC 5ASP.NET MVC 5ASP.NET MVC 5ASP.NET MVC 5 Web application framework developed by Microsoft. It is best to develop ASP.NET websites by using
Visual Studio which you can get here.
https://www.visualstudio.com/downloads/
Entity Framework 6Entity Framework 6Entity Framework 6Entity Framework 6 Entity Framework is an object-relational mapping framework for ADO.NET. It creates classes of your
tables in the database and maps it to the table in the database.
Setup: 1. Click on Tools -> NuGet Package Manager -> Package Manager Console
2. In the console enter the command ‘install-package EntityFramework’
To connect to SQL Server:
Web.config in the project is configured as: provider=System.Data.EntityClient; and
provider=System.Data.SqlClient which is the .NET Framework Data Provider for SQL Server. This uses
ADO.NET but it allows for a higher level of abstraction.
The MSDN docs are at https://msdn.microsoft.com/en-us/library/bb399567%28v=vs.110%29.aspx
and https://msdn.microsoft.com/en-us/library/ms172136%28v=vs.110%29.aspx
AJAXAJAXAJAXAJAX Ajax allows you to create client-side scripts in javascript that will allow you to communicate with the
database without refreshing the page. This is used on all of our webpages where you make some kind of
call to the database and the page is not refreshed, such as on the dashboard page.
Example: The following code will make a call to the GetEnrollments() function in the Dashboard controller and
pass in the value of data as a parameter. Then it will take the html returned from the controller and load
it where the enrollmentDash id is found.
var getEnrollments = function (data) {
$.ajax({
url: '@Url.Content($"~/Dashboard/GetEnrollments")', type: "POST",
dataType: 'html',
contentType: 'application/json',
data: data, success: function (result) {
//alert(result);
$("#enrollmentDash").html(result); },
fail: function () {
alert("Failed");
} });
};
LinqLinqLinqLinq We use Linq to query data in the database instead of using stored procedures or hand writing our SQL
queries. We have this ability because of the mapping of the tables to classes in Entity Framework. Linq is
part of the syntax in C# so no additional setup is needed to use Linq. All of our queries to the database
are done in the repositories part of our application. To use link you must put add the using statement
‘using System.Linq;’ to your file.
Example: The following query will select all of the enrollments where the area of the course contains the value in
dto.Area.
return _db.Enrollments
.Where(s => s.Schedule.area.Contains(dto.Area)) .ToList();
ExamplesExamplesExamplesExamples RetrievalRetrievalRetrievalRetrieval
Get Upcoming CoursesGet Upcoming CoursesGet Upcoming CoursesGet Upcoming Courses Navigation to: You land on the page that displays upcoming courses upon page load or by
selecting Course List in the nav bar.
When the url /Courses/Index is called you make a call to the index method in the courses
controller ( \Controllers\CoursesControler.cs ):
Using statements:
• using Rosly.Models is for the Models folder of the project
• using Rosly.ViewModels is for the ViewModels folder of the project
• using Rosly.Repositories is for the Repositories folder of the project
• using System.Linq is so Linq can be used in the file
• using System.Net is used to return specific status codes for errors in the
using Rosly.Models;
using Rosly.ViewModels; using System.Linq;
using System.Net;
using System.Web.Mvc; using Rosly.Repositories;
namespace Rosly.Controllers {
public class CoursesController : Controller
{
private readonly RoslyDbEntities _db; private readonly InstructorRepository _instructorRepository;
private readonly LocationRepository _locationRepository;
private readonly CourseRepository _courseRepository; private readonly ScheduleRepository _scheduleRepository;
public CoursesController() {
_db = new RoslyDbEntities();
_instructorRepository = new InstructorRepository(_db); _courseRepository = new CourseRepository(_db);
_locationRepository = new LocationRepository(_db);
_scheduleRepository = new ScheduleRepository(_db);
}
// GET: Courses public ActionResult Index()
{
//var sixMonthsAgo = DateTime.Now.AddMonths(-6);
var user = User.Identity.IsAuthenticated;
var viewModel = new CoursesViewModel() {
UpcomingCourses = _scheduleRepository.GetUpcomingCourses().ToList(),
Locations = _locationRepository.GetLocations().ToList(), ShowActions = user
};
return View(viewModel);
}
// Get: Courses/Create public ActionResult Create()
{
var areas = _locationRepository.GetLocations(); var instructors = _instructorRepository.GetInstructors();
//var course = db.Courses.SingleOrDefault(c => c.id == id);
var courses = _courseRepository.GetCourses();
var viewModel = new CourseFormViewModel()
{
};
return View("CourseForm", viewModel); }
// Post: Courses/Create [System.Web.Mvc.HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CourseFormViewModel viewModel) {
if (!ModelState.IsValid)
{
return View("CourseForm", viewModel); }
var course = new Course() {
description = viewModel.Description,
course_id = viewModel.CourseId };
_db.Courses.Add(course);
_db.SaveChanges();
return RedirectToAction("Index", "Courses");
}
public ActionResult Edit(int id)
{
var course = _courseRepository.GetCourse(id);
if (course == null)
{
return HttpNotFound(); }
var viewModel = new CourseFormViewModel()
{ Id = id,
CourseId = course.course_id,
Description = course.description };
return View("CourseForm", viewModel); }
[System.Web.Mvc.HttpPost]
[ValidateAntiForgeryToken] public ActionResult Update(CourseFormViewModel viewModel)
{
if (!ModelState.IsValid) {
return View("CourseForm", viewModel);
}
var course = _courseRepository.GetCourse(viewModel.Id);
if (course == null) {
return HttpNotFound();
}
course.description = viewModel.Description;
course.course_id = viewModel.CourseId;
_db.SaveChanges();
return RedirectToAction("Index", "Courses"); }
// Get: Courses/Details/5
public ActionResult Details(int? id) {
if (id == null)
{ return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var course = _courseRepository.GetCourse((int)id);
if (course == null)
{ return HttpNotFound();
}
var viewModel = new CourseDetailsViewModel()
{
//EnrolledEmployees = students,
CourseSchedule = _scheduleRepository.GetUpcomingScheduleByCourse(course),
Id = course.id, Description = course.description,
Name = course.course_id
};
return View(viewModel);
}
public ActionResult SelectCourse()
{
var courses = _courseRepository.GetCourses(); var viewModel = new CourseListViewModel()
{
Courses = courses };
return View("List", viewModel);
}
} }
The controller first checks to see if the user is logged in or not and will set the user variable to
either true or false. Then it will create a new object of type CoursesViewModel with the
properties UpcomingCourses and ShowActions. UpcomingCourses is the list of upcoming
courses that are scheduled, and ShowActions is set to the user variable determines whether or
not the user is displayed additional actions such as editing a course. The list of courses
(UpcomingCourses) is loaded by making a call to the database by using the
GetUpcomingCourses() method in the ScheduleRepository
(\Repositories\ScheduleRepository.cs) :
using System; using System.Collections.Generic;
using System.Data.Entity;
using System.Linq; using Rosly.Models;
namespace Rosly.Repositories {
public class ScheduleRepository
{ private readonly RoslyDbEntities _db;
public ScheduleRepository()
{
}
public ScheduleRepository(RoslyDbEntities db)
{ _db = db;
}
public IEnumerable<Schedule> GetUpcomingCourses()
{
return _db.Schedules
.Where(c => c.start_date >= DateTime.Now && c.is_canceled != true) .OrderBy(c => c.start_date)
.Include(c => c.Location);
}
public Schedule Find(int? id)
{ return _db.Schedules.Find(id);
}
public IEnumerable<Schedule> GetUpcomingScheduleByCourse(Course course) {
return course.Schedules.ToList();
}
public Schedule GetScheduledCourse(int id)
{ return _db.Schedules.Single(c => c.id == id);
}
} }
The GetUpcomingCourses() method queries the database for courses on the schedule that are
not cancelled and have a start date that is after the current time. The courses are then ordered
by their start date then the list of upcoming courses is returned to the Index method.
Now that view model object is created it is passed to the Courses\Index.cshtml view:
@model Rosly.ViewModels.CoursesViewModel
@{ ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<style>
.btn-info, .btn-info:hover,
.btn-info:active,
.btn-info:visited,
.btn-info:focus {
background-color: #808285;
border-color: #808285; }
.btn-primary, .btn-primary:hover,
.btn-primary:active,
.btn-primary:visited,
.btn-primary:focus { background-color: #bb2322;
border-color: #bb2322;
}
body {
padding-top: 55px; }
table {
text-align: left; }
.th { padding: 10px;
}
.custab {
border: 3px solid #808285;
padding: 5px; margin: 5% 0;
box-shadow: 3px 3px 0px #bb2322;
transition: 0.5s;
}
.custab:hover {
box-shadow: 3px 3px 3px transparent; transition: 0.5s;
}
.container {
max-width: 50000000px;
}
</style> <div class="dashhead">
<div class="dashhead-titles">
<h6 class="dashhead-subtitle">Rosly</h6> <h2 class="dashhead-title">Schedule</h2>
</div>
<div class="btn-toolbar dashhead-toolbar">
</div>
</div>
<hr class="m-t"> <div class="custyle">
@if (Model.ShowActions)
{ <a href="@Url.Action("Create", "Schedule")" class="btn btn-primary btn-xs
pull-left"><b>+</b> Create a new class</a>
}
<table class="table table-striped custab">
<thead> <tr class="tableformat">
<th>
Course Name </th>
<th>
Location
</th> <th>
Start Time
</th>
<th>
Capacity </th>
<th>
Actions
</th> </tr>
</thead>
@foreach (var course in Model.UpcomingCourses)
{
<tr>
<td> @Html.DisplayFor(model => course.Course.course_id)
</td>
<td>
@Html.DisplayFor(model => course.area) </td>
<td>
@Html.DisplayFor(model => course.start_date) </td>
<td> @course.Enrollments.Count / @course.max_capacity
</td>
<td style="text-align: center">
<a class='btn btn-primary btn-xs' href="@Url.Action("Details","Schedule",new { id = course.id })">Enroll</a>
@if (Model.ShowActions)
{ <a class='btn btn-info btn-xs'
href="@Url.Action("Edit","Schedule",new { id = course.id })">Edit</a>
} </tr>
}
</table> </div>
The model type is specified by the @model Rosly.ViewModels.CoursesViewModel. Then a
foreach loop is created to load an object for each course in the Model.UpcomingCourses (this is
the UpcomingCourses property in the view model) and display the relevant information for
each of the courses. The @if (Model.ShowActions) checks to see if the ShowActions attribute is
true and if it is, the edit button will also be displayed for each of the courses.
InsertInsertInsertInsert
Add Course to ScheduleAdd Course to ScheduleAdd Course to ScheduleAdd Course to Schedule Courses are added to the schedule from the add a course to schedule page which uses the
ScheduleForm view: \Views\Shared\ScheduleFrom.cshmtl
@model Rosly.ViewModels.ScheduleFormViewModel @{
ViewBag.Title = "ScheduleForm";
Layout = "~/Views/Shared/_Layout.cshtml"; }
@*<h2>@Model.Course.course_id</h2>*@ <h2>Schedule Form</h2>
@using (Html.BeginForm(Model.Action, "Schedule"))
{ @Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@*<div class="form-group">
@Html.HiddenFor(model => model.Course) @Html.HiddenFor(model => model.Course.course_id)
</div>*@
<div class="form-group"> @*@Html.LabelFor(model => model.Id, "Course Name")*@
@*<div class="col-md-10">*@
@Html.EditorFor(model => model.Id, new { htmlAttributes = new { @class = "form-control hide" } })
@Html.ValidationMessageFor(model => model.Id, "", new { @class = "text-danger
hide" })
@*</div>*@ </div>
<div class="form-group"> @Html.LabelFor(model => model.Course)
@Html.DropDownListFor(m => m.Course, new SelectList(Model.Courses, "id",
"course_id"), "", new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Course, "", new { @class = "text-
danger" })
</div>
<div class="form-group"> @Html.LabelFor(model => model.StartDate, "Start Date")
@*<div class="col-md-10">*@
@Html.TextBoxFor(model => model.StartDate, new { @class = "form-control", placeholder = "1 Jan 2017" })
@Html.ValidationMessageFor(model => model.StartDate, "", new { @class = "text-
danger" })
@*</div>*@ </div>
<div class="form-group"> @Html.LabelFor(model => model.StartTime, "Start Time")
@*<div class="col-md-10">*@
@Html.EditorFor(model => model.StartTime, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.StartTime, "", new { @class = "text-
danger" })
@*</div>*@ </div>
<div class="form-group"> @Html.LabelFor(model => model.Instructor)
@Html.DropDownListFor(m => m.Instructor, new SelectList(Model.Instructors,
"email", "email"), "", new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Instructor, "", new { @class = "text-danger" })
</div>
<div class="form-group">
@Html.LabelFor(model => model.Area)
@*<div class="col-md-10">*@
@Html.DropDownListFor(m => m.Area, new SelectList(Model.Areas, "area", "area"), "", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Area, "", new { @class = "text-danger" })
@*</div>*@ </div>
<div class="form-group"> @Html.LabelFor(model => model.MaxCapacity, "Max Capacity")
@*<div class="col-md-10">*@
@Html.EditorFor(model => model.MaxCapacity, new { htmlAttributes = new {
@class = "form-control" } }) @Html.ValidationMessageFor(model => model.MaxCapacity, "", new { @class =
"text-danger" })
@*</div>*@ </div>
@*<div class="form-group"> <div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>*@ <button type="submit" class="btn btn-primary" onclick="alerttest()">Save</button>
@*</div>*@
}
<div>
@Html.ActionLink("Back to List", "Index", "Courses")
</div>
@section scripts
{
@Scripts.Render("~/bundles/jqueryval") }
The schedule form view uses the ScheduleFormViewModel. The form uses each field to create
the value of the given property in the \ViewModels\ScheduleFormViewModel.cshtml :
Using Statements
• System.ComponentModel.DataAnnotations allows the ability to create restrictions for
each property such as making it required or to set the max length of a string
• Rosly.Models is the folder containing the models for the project
• Rosly.Controllers is the folder containing the controllers for the project
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.Linq.Expressions;
using System.Web.Mvc;
using Rosly.Controllers; using Rosly.Models;
namespace Rosly.ViewModels
{ public class ScheduleFormViewModel
{
public int Id { get; set; }
//[Required]
//[MaxLength(10)] //public string CourseId { get; set; }
[Required]
public int Course { get; set; }
//public Course Course { get; set; }
public IEnumerable<Course> Courses { get; set; }
[Required]
public string StartDate { get; set; }
[Required]
public string StartTime { get; set; }
public string EndDate { get; set; }
[Required] public string Area { get; set; }
public IEnumerable<Location> Areas { get; set; }
[Required]
public int MaxCapacity { get; set; }
[Required] public string Instructor { get; set; }
public IEnumerable<Instructor> Instructors { get; set; }
public string Action
{
get {
Expression<Func<ScheduleController, ActionResult>> update =
(c => c.Update(this));
Expression<Func<ScheduleController, ActionResult>> create =
(c => c.Create(this));
var action = (Id != 0) ? update : create;
return (action.Body as MethodCallExpression).Method.Name; }
}
public DateTime GetDateTime()
{
return DateTime.Parse(string.Format("{0} {1}", StartDate, StartTime)); }
}
}
The Action method in the view model checks to see what method called the view model so the
appropriate fields can be displayed in the view. When the form is submitted it calls the create
method in the schedule controller : \Controllers\ScheduleController.cs
using System;
using System.Collections.Generic;
using System.Linq; using System.Net;
using System.Web;
using System.Web.Mvc;
using Rosly.Models; using Rosly.Repositories;
using Rosly.ViewModels;
namespace Rosly.Controllers
{
public class ScheduleController : Controller {
private readonly RoslyDbEntities _db;
private readonly LocationRepository _locationRepository;
private readonly ScheduleRepository _scheduleRepository; private readonly CourseRepository _courseRepository;
private readonly InstructorRepository _instructorRepository;
public ScheduleController()
{
_db = new RoslyDbEntities(); _courseRepository = new CourseRepository(_db);
_scheduleRepository = new ScheduleRepository(_db);
_locationRepository = new LocationRepository(_db); _instructorRepository = new InstructorRepository(_db);
}
// GET: Schedule
public ActionResult Index()
{
return View(); }
// Get: Courses/Create [Authorize]
public ActionResult Create()
{ var areas = _locationRepository.GetLocations();
var instructors = _instructorRepository.GetInstructors();
//var course = _db.Courses.SingleOrDefault(c => c.id == id);
var courses = _courseRepository.GetCourses();
var viewModel = new ScheduleFormViewModel()
{ Areas = areas,
Instructors = instructors,
Courses = courses };
return View("ScheduleForm", viewModel); }
// Post: Courses/Create
[HttpPost] [ValidateAntiForgeryToken]
[Authorize]
public ActionResult Create(ScheduleFormViewModel viewModel) {
if (!ModelState.IsValid)
{ viewModel.Areas = _locationRepository.GetLocations();
viewModel.Instructors = _instructorRepository.GetInstructors();
//viewModel.Course = viewModel.Course;
viewModel.Courses = _courseRepository.GetCourses();
return View("ScheduleForm", viewModel);
}
var course = new Schedule()
{ Course = _courseRepository.GetCourse(viewModel.Course),
start_date = viewModel.GetDateTime(),
end_date = viewModel.GetDateTime(),
area = viewModel.Area, Instructor = _instructorRepository.GetInstructor(viewModel.Instructor),
max_capacity = viewModel.MaxCapacity,
num_of_students = 0, };
_db.Schedules.Add(course);
_db.SaveChanges();
return RedirectToAction("Index", "Courses");
}
[Authorize]
public ActionResult Edit(int id)
{
var course = _scheduleRepository.GetScheduledCourse(id);
if (course == null)
return HttpNotFound();
var viewModel = new ScheduleFormViewModel()
{ Id = id,
StartDate = course.start_date.ToString("d MMM yyyy"),
StartTime = course.start_date.ToString("HH:mm"),
Areas = _locationRepository.GetLocations(), Area = course.area,
MaxCapacity = course.max_capacity,
Courses = _courseRepository.GetCourses(), Instructors = _instructorRepository.GetInstructors(),
Instructor = course.Instructor.email,
Course = course.Course.id };
return View("ScheduleForm", viewModel); }
[HttpPost]
[ValidateAntiForgeryToken] [Authorize]
public ActionResult Update(ScheduleFormViewModel viewModel)
{ if (!ModelState.IsValid)
{
viewModel.Areas = _locationRepository.GetLocations(); viewModel.Courses = _courseRepository.GetCourses();
viewModel.Instructors = _instructorRepository.GetInstructors();
return View("ScheduleForm", viewModel); }
var course = _scheduleRepository.GetScheduledCourse(viewModel.Id);
var instructor = _instructorRepository.GetInstructor(viewModel.Instructor);
course.Modify(viewModel.GetDateTime(), viewModel.Area, instructor, viewModel.MaxCapacity);
//course.course_id = viewModel.CourseId;
//course.start_date = viewModel.GetDateTime();
//course.area = viewModel.Area; //course.Instructor = _db.Instructors.Single(i => i.email ==
viewModel.Instructor);
////course.description = viewModel.Description; //course.max_capacity = viewModel.MaxCapacity;
_db.SaveChanges();
return RedirectToAction("Index", "Courses"); }
// Get: Courses/Details/5 public ActionResult Details(int? id)
{
if (id == null)
{ return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var schedule = _scheduleRepository.Find(id);
if (schedule == null)
{ return HttpNotFound();
}
var students = schedule.Enrollments.Select(e => e.Employee);
var viewModel = new ScheduleDetailsViewModel()
{ EnrolledEmployees = students,
Area = schedule.area,
Id = schedule.id, StartDate = schedule.start_date.ToString("MMM dd, yyyy"),
NumOfStudents = schedule.num_of_students,
MaxCapacity = schedule.max_capacity, Description = schedule.Course.description,
Name = schedule.Course.course_id
};
return View(viewModel);
}
} }
The controller will then check to see if the fields are valid or not, if they are not it will return the
user back to the form. If the fields are valid it will create a new Schedule object :
\Models\Schedule.cs :
namespace Rosly.Models
{ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Linq;
using Rosly.Services;
using Outlook = Microsoft.Office.Interop.Outlook;
public partial class Schedule
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Schedule()
{ this.Enrollments = new Collection<Enrollment>();
this.Notifications = new HashSet<Notification>();
}
public int id { get; set; }
public System.DateTime start_date { get; set; } public System.DateTime end_date { get; set; }
public string area { get; set; }
public int max_capacity { get; set; }
public int num_of_students { get; set; } public Nullable<bool> is_canceled { get; private set; }
public int course_id { get; set; }
public int instructor_id { get; set; }
public virtual Course Course { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual Instructor Instructor { get; set; }
public virtual Location Location { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage",
"CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<Notification> Notifications { get; set; }
public void Cancel() {
is_canceled = true;
var notification = Notification.CourseCanceled(this);
//var attendees = db.Enrollments
// .Where(e => e.schedule_id == course.id) // .Select(e => e.Employee)
// .ToList();
EmailService emailService = new EmailService(notification); emailService.CancelCourse();
foreach (var employee in Enrollments.Select(e => e.Employee))
{ employee.Notify(notification, true);
//SendNotification(employee.email);
} }
private void SendNotification(string email) {
try
{ Outlook._Application _app = new Outlook.Application();
Outlook.MailItem mail =
(Outlook.MailItem)_app.CreateItem(Outlook.OlItemType.olMailItem);
mail.To = email; mail.Subject = "Course Cancelled";
mail.Body = "The course you enrolled in was cancelled";
mail.Importance = Outlook.OlImportance.olImportanceNormal; ((Outlook._MailItem)mail).Send();
Console.WriteLine("Your email was sent successfully.");
}
catch (Exception e)
{ Console.WriteLine("Error sending email" + e.ToString());
throw;
}
}
public void Modify(DateTime dateTime, string area, Instructor instructor, int MaxCapacity)
{
if (is_canceled == true) return;
var notification = Notification.CourseUpdated(this, start_date, area);
start_date = dateTime;
this.area = area;
Instructor = instructor; max_capacity = MaxCapacity;
EmailService emailService = new EmailService(notification); emailService.AlterMeeting(notification);
foreach (var employee in Enrollments.Select(e => e.Employee)) {
employee.Notify(notification, true);
} }
public void Enroll(Employee employee)
{ if (is_canceled == true)
return;
var enrollment = new Enrollment()
{
Employee = employee, Schedule = this,
timestamp = DateTime.Now
};
Enrollments.Add(enrollment);
var notification = Notification.EmployeeEnrolled(this);
employee.SendInvite(notification, this, true); }
}
}
To set the Course value it will make a call to the GetCourse in the Course repository :
\Repositories\CourseRepository.cs :
using System;
using System.Collections.Generic; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Rosly.Models;
namespace Rosly.Repositories
{
public class CourseRepository {
private readonly RoslyDbEntities _db;
public CourseRepository(RoslyDbEntities db) {
_db = db;
}
public Course GetCourse(int id)
{ return _db.Courses.Single(c => c.id == id);
}
public IEnumerable<Course> GetCourses() {
return _db.Courses.ToList();
} }
}
The GetCourse method will return a single course that has the same id as the given value.
To set the value of the
HomeHomeHomeHome Home PageHome PageHome PageHome Page
ViewsViewsViewsViews
Home • \Home\Index.cshtml
ViewModelsViewModelsViewModelsViewModels
None
ControllersControllersControllersControllers
Home • Index
RepositoriesRepositoriesRepositoriesRepositories
None
CourseCourseCourseCourse CreateCreateCreateCreate
ViewsViewsViewsViews
Shared • \Shared\_Layout.cshtml
• \Shared\CourseForm.cshtml
o Course Name – String max 10 characters
o Description – String max
ViewModelsViewModelsViewModelsViewModels • \ViewModels\CourseFormViewModel.cs
ControllersControllersControllersControllers
CoursesController • \Controllers\CoursesController.cs
o Create(): Creates course then returns to schedule.
RepositoriesRepositoriesRepositoriesRepositories
None
EditEditEditEdit
ViewsViewsViewsViews
Shared • \Shared\_Layout.cshtml
• \Shared\CourseForm.cshtml
o Course Name – String max 10 characters
o Description – String max
ViewModelsViewModelsViewModelsViewModels • \ViewModels\CourseFormViewModel.cs
ControllersControllersControllersControllers
Courses • \Controllers\CoursesController.cs
o Edit(): loads CourseForm and fills with appropriate info calls Update() method on button
press
o Update: checks if input is valid. If input is valid course is updated then returns to the
schedule
RepositoriesRepositoriesRepositoriesRepositories
CourseRepository • \Repositories\CourseRepository.cs
o GetCourse() – finds a single course by its id
DetailsDetailsDetailsDetails
ViewsViewsViewsViews
Shared • \Views\Shared\_Layout.cshtml
Courses • \Views\Courses\Details.cshtml
o Description: Description of course
o Course Schedule: Shows date, time, and location of upcoming classes for given course
o Register Button: Takes you to course registration page
ViewModelsViewModelsViewModelsViewModels • \ViewModels\CourseDetailsViewModel.cs
ControllersControllersControllersControllers
CoursesController • \Controllers\CoursesController.cs
o Details() : shows details of the course and upcoming classes for the course
RepositoriesRepositoriesRepositoriesRepositories
ScheduleRepository • \Repositories\ScheduleRepository.cs
o GetUpcomingScheduleByCourse() : returns upcoming schedule for a given course
CourseRepository • \Repositories\CourseRepository.cs
o GetCourse() : returns a single course by its id
ScheduleScheduleScheduleSchedule
IndexIndexIndexIndex
ViewsViewsViewsViews
Shared • \Views\Shared\_Layout.cshmtl
Courses • \Views\Courses\Index.cshtml
o Course Name: Name of course
o Location: Location of course
o Start Time: Start date and time of course
o Capacity: How many students are enrolled and the max capacity
o Actions: Actions to be performed on a course
ViewModelsViewModelsViewModelsViewModels • \ViewModels\CoursesViewModel.cs
ControllersControllersControllersControllers
Courses • \Controllers\CoursesController.cs
o Index() : Shows list of upcoming courses
RepositoRepositoRepositoRepositoriesriesriesries
ScheduleRepository • \Repositories\ScheduleRepository.cs
o GetUpcomingCourses() : Returns a list of upcoming courses
LocationRepository • \Repositories\LocationRepository.cs
o GetLocations() : Returns a list of all locations
Add Course To ScheduleAdd Course To ScheduleAdd Course To ScheduleAdd Course To Schedule
ViewsViewsViewsViews
Shared • \Views\Shared\_Layout.cshtml
• \Views\Shared\ScheduleForm.cshtml
o Courses Dropdown – select course you would like to add to schedule
o Start Date – date the course will be taught
o Start Time – time the course will be taught
o Instructor dropdown – select instructor who will be teaching course. Shows their email
o Area dropdown – Location the course will be taught
o Max Capacity – Total number of employees that can take this course
ViewModelsViewModelsViewModelsViewModels • \Views\Shared\ScheduleFormViewModel.cs
ControllersControllersControllersControllers
ScheduleController • \Controllers\ScheduleController.cs
o Create(): add course to schedule for employees to enroll in.
RepositoryRepositoryRepositoryRepository
LocationRepository • \Repositories\LocationRepository.cs
o GetLocations() : Returns list of all locations
InstructorRepository • \Repositories\InstructorRepository.cs
o GetInstructors() : Returns list of all instructors
CourseRepository • \Repositories\CourseRepository.cs
o GetCourses() : Returns list of all courses
EditEditEditEdit
ViewsViewsViewsViews
Shared • _Layout.cshtml
Courses • Details.cshtml
o Description: Description of course
o Course Schedule: Shows date, time, and location of upcoming classes for given course
o Register Button: Takes you to course registration page
ViewModelsViewModelsViewModelsViewModels • \ViewModels\CourseDetailsViewModel.cs
ControllersControllersControllersControllers
ScheduleController • \Controllers\ScheduleController.cs
o Edit() : Edit the details of the scheduled course. Create notifications for enrolled
employees.
RepositoriesRepositoriesRepositoriesRepositories
LocationRepository • \Repositories\LocationRepository.cs
o GetLocations() : Returns list of all locations
CourseRepository • \Repositories\CoursesRepository.cs
o GetCourses() : Returns list of all courses
InstructorRepository • \Repositories\InstructorRepository.cs
o GetInstructors() : Returns list of all instructors
ScheduleRepository • \Repositories\ScheduleRepository.cs
o GetScheduledCourse() : Returns a single scheduled course
DetailsDetailsDetailsDetails
ViewsViewsViewsViews
Shared • \Views\Shared\_Layout.cshtml
Schedule • \Views\Schedule\Details.cshtml
o Name: Name of course
o Date: Start time/date of course
o Location: location course is being taught at
o Description: description of course
o Capacity: (Number of students enrolled) / (Max Capacity)
o Enrolled Employees: List of employees enrolled in course
ViewModelsViewModelsViewModelsViewModels • ScheduleDetailsViewModel.cs
ControllersControllersControllersControllers
Schedule • \Controlelrs\ScheduleController.cs
o Details(): Get details of a scheduled course including who is enrolled in it.
RepositoryRepositoryRepositoryRepository
ScheduleRepository • \Repositories\ScheduleRepository.cs
o Find() : Returns a single scheduled course
EmployeeEmployeeEmployeeEmployee Enroll employeeEnroll employeeEnroll employeeEnroll employee
ViewsViewsViewsViews
Shared • \Views\Shared\_Layout.cshtml
• \Views\Shared\EmployeeForm.cshtml
o Last Name (Required) – String max length 20 characters. Maps to LastName in view
model.
o First Name (Required) – String max length 20 characters. Maps to FirstName in view
model.
o Email (required) – String maxlength 254 characters. Maps to email in view model
ViewModelsViewModelsViewModelsViewModels • EmployeeFormViewModel.cs
ControllersControllersControllersControllers
EmployeeController • \Controllers\EmployeeController.cs
o Enroll() : enrolls employee in course. If employee does not exist takes them to form for
enrolling new employees.
RepositoriesRepositoriesRepositoriesRepositories
LocationRepository • \Repositories\LocationRepository.cs
o GetLocations() : Returns all locations
EmployeeRepository • \Repositories\EmployeeRepository.cs
o GetEmployee() : Returns a single employee by id
EnrollmentRepository • \Repositories\EnrollmentRepository.cs
o IsEnrolled() : Returns true or false if employee is enrolled or not
ScheduleRepository • \Repositories\ScheduleRepository.cs
o GetScheduledCourse() : Returns a scheduled course
Enroll New EmployeeEnroll New EmployeeEnroll New EmployeeEnroll New Employee
ViewsViewsViewsViews
Shared • \Views\Shared\_Layout.cshtml
• \Views\Shared\EmployeeForm.cshtml
o Last Name (Required) – String max length 20 characters. Maps to LastName in view
model.
o First Name (Required) – String max length 20 characters. Maps to FirstName in view
model.
o Email (required) – String maxlength 254 characters. Maps to email in view model
o Business Unit (required) – String max length 10 characters. Maps to BusUnit in view
model.
o Cost Center (required) – Long. Maps to CostCent in view model.
o Cube Location (required) – String. Maps to CubeLocation in view model.
o Area dropdown (required) – Drop down of locations. Maps to Area in view model.
o Employee id – Long. Maps to EmployeeId in view model.
ViewModelsViewModelsViewModelsViewModels • EmployeeFormViewModel.cs
ControllersControllersControllersControllers
EmployeeController • \Controllers\EmployeeController.cs
o EnrollAndCreate(): Creates new employee then enrolls them into the scheduled course
RepositoriesRepositoriesRepositoriesRepositories
LocationRepository • \Repositories\LocationRepository.cs
o GetLocations() : returns all locations
ScheduleRepository • \Repositories\ScheduleRepository.cs
o GetScheduledCourse() : returns a single scheduled course
EmployeeRepository • \Repositories\EmployeeRepository.cs
o GetEmployee() : returns a single employee
DashboardDashboardDashboardDashboard ReportsReportsReportsReports
ViewsViewsViewsViews
Shared • Views\Shared\_Layout.cshtml
Dashboard • \Views\Dashboard\Index.cshtml
o \Views\Dashboard\CourseChartPartialView.cshtml
o \Views\Dashboard\LocationsPartialView.cshtml
o \Views\Dashboard\GetEnrollments.cshtml
ViewModelsViewModelsViewModelsViewModels • DashboardViewModel.cs
• HiddenFieldsViewModel.cs
• EnrollmentDashboardViewModel.cs
ControllersControllersControllersControllers
DashboardController • \Controllers\DashboardController.cs
o Index(): Loads the index.cshtml view
o HiddenFields(): Stores values selected for the dashboard
o GetEnrollments(): Loads the table of enrolled employees based on selected values
RepositoriesRepositoriesRepositoriesRepositories
LocationRepository • \Repositories\LocationRepository.cs
o GetLocations() : returns all locations
CourseRepository • \Repositories\CourseRepository.cs
o GetCourses() : returns all courses
ScheduleRepository • \Repositories\ScheduleRepository.cs
o GetUpcomingCourses() : returns all upcoming courses on schedule
EnrollmentRepository • \Repositories\EnrollmentRepository.cs
o FindEnrollments() : returns enrollments based on search parameters