INF3003W Cheat Sheet
INF3003W Cheat Sheet
○ Constructor approach
public SchoolContext() :
base("Server=localhost;Database=SchoolDB;Trusted_Connection=True;")
"ConnectionStrings": {
"SchoolContext":
"Server=localhost;Database=SchoolDB;Trusted_Connection=True;"
● Startup.cs Configuration:
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")))
;
}
_connectionString = connectionString;
optionsBuilder.UseSqlServer(_connectionString);
var connectionString =
Configuration.GetConnectionString("SchoolContext");
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(connectionString));
● Explanation: The connection string is stored externally and injected into SchoolContext through
dependency injection, providing flexibility and making it easier to manage connection strings in
different environments (e.g., development, testing, production).
RazorPages:
● ASP.NET Identity Authentication:
○ Update the database:
■ update-database
○ Configure the identity services:
■
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;
builder.Services.Configure<IdentityOptions>(options =>
{
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
// Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings.
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = false;
});
builder.Services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
Email = email;
// Once you add a real email sender, you should remove this code that lets you confirm the
account
DisplayConfirmAccountLink = false;
if (DisplayConfirmAccountLink)
{
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
EmailConfirmationUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
}
return Page();
}
}
● Add the Products and OrderItem links to the _Layout.cshtml page
○
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
● Sorting functionality:
○ How to edit page to remove the productID
○ Pages/Products/index.cshtml
○ Comment out the @Html.DisplayFor or @Html.DisplayNameFor related to productID.
namespace MPNKAB004_NovExam.Pages.Products
{
public class IndexModel : PageModel
{
CurrentPage = pageNumber ?? 1;
IQueryable<Product> productsQuery = _context.Product;
// Apply sorting
switch (sortOrder)
{
case "name_desc":
productsQuery = productsQuery.OrderByDescending(p => p.productName);
break;
case "Price":
productsQuery = productsQuery.OrderBy(p => p.productPrice);
break;
case "price_desc":
productsQuery = productsQuery.OrderByDescending(p => p.productPrice);
break;
default:
productsQuery = productsQuery.OrderBy(p => p.productName);
break;
}
// Apply paging
Product = await productsQuery
.Skip((CurrentPage - 1) * PageSize)
.Take(PageSize)
.ToListAsync();
○ Pages/Products/Index.cshtml
○ Below the </tbody> and </table>
○
<ul class="pagination">
</li>
</li>
</ul>
</nav>
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
{
options.SignIn.RequireConfirmedAccount = false;
})
builder.Services.AddRazorPages();
app.UseHttpsRedirection();
…
app.Run();
namespace ContosoUniversity
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddControllersWithViews();
}
}
}
},
"AllowedHosts": "*"
}
namespace ContosoUniversity.Data
{
public class SchoolContext : DbContext
{
public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
{
}
try
{
_context.Students.Remove(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
// Asynchronously retrieve the student with the given ID from the database.
// "FirstOrDefaultAsync" returns the first matching student or null if no match is found.
if (await TryUpdateModelAsync<Student>(
studentToUpdate,
"",
s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate))
// "TryUpdateModelAsync" attempts to update the student entity with values from the form submission.
// Only specified properties (FirstMidName, LastName, EnrollmentDate) are updated to prevent overposting.
{
try
{
await _context.SaveChangesAsync();
// Save the changes to the database asynchronously.
return RedirectToAction(nameof(Index));
// Redirect the user back to the "Index" action if the update is successful.
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " +
"see your system administrator.");
}
}
return View(studentToUpdate);
}
switch (sortOrder)
{
case "name_desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "date_desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.LastName);
break;
}
return View(await students.AsNoTracking().ToListAsync());
}
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
<a asp-action="Index" asp-route-
sortOrder="@ViewData["NameSortParm"]">@Html.DisplayNameFor(model =>
model.LastName)</a>
</th>
<th>
@Html.DisplayNameFor(model => model.FirstMidName)
</th>
<th>
<a asp-action="Index" asp-route-
sortOrder="@ViewData["DateSortParm"]">@Html.DisplayNameFor(model =>
model.EnrollmentDate)</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
@Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
○ Filtering:
■ Adding filtering functionality in the studentcontroller:
●
//added the string searchString parameter to the index method
public async Task<IActionResult> Index(string sortOrder, string searchString)
{
ViewData["NameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewData["DateSortParm"] = sortOrder == "Date" ? "date_desc" : "Date";
ViewData["CurrentFilter"] = searchString;
<table class="table">
○ Paging:
■ Creating and adding a paginatedlist class to the project:
●
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace ContosoUniversity
{
public class PaginatedList<T> : List<T>
{
public int PageIndex { get; private set; }
public int TotalPages { get; private set; }
this.AddRange(items);
}
if (searchString != null)
{
pageNumber = 1;
}
else
{
searchString = currentFilter;
}
ViewData["CurrentFilter"] = searchString;
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
<a asp-action="Index" asp-route-sortOrder="@ViewData["NameSortParm"]"
asp-route-currentFilter="@ViewData["CurrentFilter"]">Last Name</a>
</th>
<th>
First Name
</th>
<th>
<a asp-action="Index" asp-route-sortOrder="@ViewData["DateSortParm"]" asp-
route-currentFilter="@ViewData["CurrentFilter"]">Enrollment Date</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
@Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
@{
var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.HasNextPage ? "disabled" : "";
}
<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-pageNumber="@(Model.PageIndex - 1)"
asp-route-currentFilter="@ViewData["CurrentFilter"]"
class="btn btn-default @prevDisabled">
Previous
</a>
<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-pageNumber="@(Model.PageIndex + 1)"
asp-route-currentFilter="@ViewData["CurrentFilter"]"
class="btn btn-default @nextDisabled">
Next
</a>
1. Documentation
● Guidelines and Rules for each diagram:
● Class Diagram
● Activity Diagram
● Use case Diagram & Use case Narrative
● Sequence Diagram
● State Machine Diagram
● Package Diagram
Reflection Essay
● What?
During the course of the project, I encountered several challenges while learning new technologies, such as
WordPress, PHP, FileZilla, and responsive design. Although WordPress was user-friendly and easy to grasp, PHP
presented a steep learning curve. Our entire team struggled with understanding and implementing PHP,
especially database interactions, as none of us had prior experience. This lack of familiarity led to frequent
coding errors, numerous late nights troubleshooting in the labs, and an overwhelming sense of frustration.
Responsive design, although not entirely new, also proved challenging as I faced difficulties ensuring the website
functioned smoothly across various screen sizes. I often had to revisit and tweak the code to maintain
consistency.
● So What?
Initially, I felt overwhelmed and under immense pressure to learn these new skills under tight deadlines. This
experience forced me to adopt a more structured approach to self-learning and shifted my perception of what it
takes to acquire technical expertise in a fast-paced, practical environment. I realized that persistence and
resilience are essential when faced with setbacks. I had to reassess and refine my strategies for self-teaching,
acknowledging that consistent effort and practice are critical for success.
● Now What?
I now understand that learning is a continuous process that involves embracing mistakes and using them as
opportunities for growth. Since this experience, I have adopted a more patient and methodical approach to skill
acquisition. I have learned to appreciate the importance of consistent practice and have become more willing to
embrace challenges, recognizing that genuine learning often comes from repeated trial and error. This
experience has also given me a clearer view of the professional world and the level of adaptability required to
succeed.
2. Team Dynamics
● What?
At the beginning of the year, our team of 5 or 6 students started off with promising dynamics. Everyone appeared
eager to collaborate and get to know each other. However, as time went on, the dynamics began to deteriorate.
Some members became passive-aggressive and dismissive, openly criticizing my suggestions. The group
atmosphere grew hostile, with frequent disagreements, particularly over my ideas. One member would even
interrupt and speak over me, contributing to the growing tension. Despite my attempts to reconcile by reaching
out to certain members and suggesting compromises, my efforts were often met with indifference. Meetings felt
awkward and unproductive, and our progress stalled. Ironically, we produced high-quality deliverables, such as a
report that earned a 90%, but the disjointed group environment left me feeling frustrated and discouraged.
● So What?
At the time, I felt a mix of frustration and helplessness. Despite trying to promote better communication and
collaboration, I couldn’t shake the feeling that I was the source of the conflict. I noticed that the other team
members had good relationships among themselves, which intensified my sense of isolation. To manage the
tension, I suggested moving meetings online to avoid the discomfort of in-person interactions. Reflecting now, I
realize I could have approached the situation differently. I was too passive in confronting issues early on and
hesitant to insist on clearer communication and mutual respect. I have also come to understand that some
members may have been dealing with personal or academic struggles that influenced their behavior.
● Now What?
Moving forward, I recognize the need to be more proactive in addressing conflicts. In future team settings, I
would address interpersonal issues directly and constructively, possibly through one-on-one conversations.
Avoiding the problems only exacerbated the tension. Additionally, I intend to learn conflict resolution strategies
to better handle challenging group dynamics. I also recognize the importance of empathy and understanding
that others may be facing challenges I am unaware of.
● What?
Last week, our team presented our website to our mentor, sponsor, and key stakeholders at a crucial milestone
on campus at Leslie Commerce. This presentation was an opportunity to showcase our work, receive feedback,
and ensure alignment with our stakeholders' expectations. Balancing the pressure of delivering a polished
presentation with the anticipation of constructive criticism made this experience both nerve-wracking and
valuable.
● So What?
Initially, I was a bundle of nerves, worried about whether we had met all the expectations. Presenting under
pressure felt daunting, but the constructive feedback we received from our lecturers was reassuring. This
feedback shifted my perspective, helping me realize the value of critique in professional growth. Reflecting on
this, I see that my initial fears were misplaced. The experience highlighted the importance of confidence,
preparation, and the willingness to learn from feedback. It was an essential step in my development as a software
developer and a valuable learning moment for the team.
● Now What?
This experience taught me the importance of clear communication with stakeholders and staying composed
under pressure. I will focus on being more proactive and confident in my role, making an effort to enjoy the
process rather than fixating solely on deliverables. Additionally, I aim to embrace feedback as a tool for growth,
using it to refine my skills and contribute more effectively. My advice to future students is to view these
challenging moments as opportunities for learning and self-improvement, as they often bring out your true
potential.