Setting-up-with-Database
Setting-up-with-Database
1. UserName Model
namespace lesson1.Models
{
public class UserName
{
[Required(ErrorMessage = "Username is required.")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+=-])[a-zA-Z0-
9!@#$%^&*()_+=-]+$",
ErrorMessage = "Username must contain at least one lowercase letter, one uppercase
letter, one digit, and one special character (!@#$%^&*()_+=-).")]
[StringLength(20, MinimumLength = 8, ErrorMessage = "Username must be between 8
and 20 characters long.")]
public string username { get; set; }
using lesson1.Models;
using Microsoft.AspNetCore.Mvc;
using System.IO; // new
using System.Text; // new
using BCrypt.Net; // new
namespace lesson1.Controllers
{
public class UsernameController : Controller
{
// new
private readonly string filePath = @"C:\Users\THOR\Desktop\UD-
R\UserCredentials.txt";
[HttpPost]
public ActionResult Index(UserName unamemodel)
{
if (ModelState.IsValid)
{
// Hash the password before saving
string hashedPassword =
BCrypt.Net.BCrypt.HashPassword(unamemodel.password);
// new
ViewBag.Message = $"Username '{unamemodel.username}' saved!";
}
// new
ViewBag.Usernames = System.IO.File.Exists(filePath) ?
System.IO.File.ReadAllText(filePath) : "No usernames saved yet.";
return View();
}
}
}
using directive in C#
using System.IO;
"Fully qualify" means writing the full path of a class, function, or interface, including its
namespace.
System.Console.WriteLine("Hello, world!");
But if you add using System; at the top, you can simply write:
Console.WriteLine("Hello, world!");
using System.Text;
using BCrypt.Net;
What is BCrypt.Net?
• private means this variable can only be accessed within the same class.
• It cannot be accessed from other classes or outside the class it's declared in.
2. readonly (Modifier)
• You can assign a value inside the constructor, but you cannot modify it later.
Summary
private Accessible only within the class.
readonly Cannot be modified after initialization.
string Stores a text value.
filePath Variable name storing the path to a file.
= ... Assigns the file path value.
@ Verbatim string to prevent escape sequence issues in the file path.
return View();
}
1. ViewBag.Usernames =
• ViewBag: A dynamic object in ASP.NET MVC used to pass data from the
controller to the view.
• File.Exists(filePath):
3. ? : (Ternary Operator)
4. System.IO.File.ReadAllText(filePath)
• Reads the entire contents of the file located at filePath and returns it as a string.
• If the file contains multiple usernames, they will be retrieved as a single string.
• If the file does not exist, this default string is assigned to ViewBag.Usernames.
[HttpPost]
public ActionResult Index(UserName unamemodel)
{
if (ModelState.IsValid)
{
// Hash the password before saving
string hashedPassword = BCrypt.Net.BCrypt.HashPassword(unamemodel.password);
ViewBag.Usernames = System.IO.File.Exists(filePath) ?
System.IO.File.ReadAllText(filePath) : "No usernames saved yet.";
return View();
}
}
1. string hashedPassword =
• hashedPassword: A variable that will store the hashed version of the user's
password.
This part is responsible for hashing the password. Let’s break it down:
🔹 BCrypt.Net.BCrypt
🔹 unamemodel.password
1. string userData =
• userData: The name of the variable that will hold the formatted string.
2. $"{unamemodel.username} | {hashedPassword}\n"
🔹 {unamemodel.username}
• A separator (pipe symbol |) is used between the username and the hashed
password.
🔹 {hashedPassword}
• Inserts the value of hashedPassword (the securely hashed password) into the
string.
🔹 \n (Newline Character)
• \n adds a new line, meaning each stored username-password pair will be written
on a separate line in the text file.
1. System.IO.File
• File: A class in System.IO that contains static methods for working with files,
such as reading, writing, and appending text.
1. filePath: The path to the file where the data will be written.
@model lesson1.Models.UserName
<!DOCTYPE html>
<html>
<body>
<h2>Enter Credentials</h2>
@using (Html.BeginForm(FormMethod.Post))
{
<div class="mb-3">
@Html.LabelFor(model => model.username, "Username:", new { @class =
"form-label" })
@Html.TextBoxFor(model => model.username, new { @class = "form-control",
placeholder = "Enter your username" })
@Html.ValidationMessageFor(model => model.username, "", new { @class =
"text-danger" })
</div>
<div class="mb-3">
@Html.LabelFor(model => model.password, "Password:", new { @class =
"form-label" })
@Html.PasswordFor(model => model.password, new { @class = "form-
control", placeholder = "Enter your password" })
@Html.ValidationMessageFor(model => model.password, "", new { @class =
"text-danger" })
</div>
@* NEW *@
<h3>Saved Usernames and Hashed Passwords:</h3>
<pre>@ViewBag.Usernames</pre>
</body>
</html>
Add below
// new
return RedirectToAction("Success");
}
// new
return View(unamemodel);
}
// new
public ActionResult Success()
{
return View();
}
}
}
<!DOCTYPE html>
<html>
<body>
<h2>Form Submitted Successfully!</h2>
<p>Your credentials have been saved.</p>
Changes Made:
• After submitting, the user is redirected to a login page where they enter their
credentials to retrieve stored data.
• If login credentials match the stored username and password, redirect to a
success page.
• Used BCrypt.Verify to check if the entered password matches the stored hashed
password.
namespace lesson1.Controllers
{
public class UsernameController : Controller
{
ViewBag.Usernames = System.IO.File.Exists(filePath) ?
System.IO.File.ReadAllText(filePath) : "No usernames saved yet.";
return View();
}
[HttpPost]
public ActionResult Index(UserName unamemodel)
{
if (ModelState.IsValid)
{
string hashedPassword =
BCrypt.Net.BCrypt.HashPassword(unamemodel.password);
// new
return RedirectToAction("Login");
}
ViewBag.Usernames = System.IO.File.Exists(filePath) ?
System.IO.File.ReadAllText(filePath) : "No usernames saved yet.";
return View(unamemodel);
}
// new
public ActionResult Login()
{
return View();
}
// new
[HttpPost]
public IActionResult Login(string username, string password)
{
if (System.IO.File.Exists(filePath))
{
string[] lines = System.IO.File.ReadAllLines(filePath);
return RedirectToAction("Login");
[HttpPost]
public IActionResult Login(string username, string password)
1. [HttpPost] (Attribute)
• This attribute indicates that the method should handle HTTP POST requests.
• It means the Login action is triggered when the form is submitted via the POST
method.
• This specifies that the method is accessible from other parts of the application,
including the client (browser) making a request.
if (System.IO.File.Exists(filePath))
1. if (Conditional Statement)
• This is a control flow statement that checks whether a condition is true.
• If the condition inside the parentheses evaluates to true, the code inside the if
block executes.
• If it's false, the block is skipped.
2. System.IO (Namespace)
3. File (Class)
• It takes a string parameter (filePath), which represents the full path of the file to
check.
5. filePath (Variable)
• Each element in this array represents a single line from the file.
2. lines (Variable Name)
• This is the name of the variable that stores the lines read from the file.
3. = (Assignment Operator)
5. File (Class)
• File is a static class inside System.IO that provides various methods for working
with files.
• It reads all lines from the file and returns them as an array of strings (string[]),
where each element represents a line in the file.
7. filePath (Variable)
• filePath is a variable that stores the location of the file (e.g.,
"C:\\Users\\THOR\\Desktop\\UD-R\\UserCredentials.txt").
• This is the file from which ReadAllLines() reads data.
foreach (string line in lines) {
o A loop that iterates over each element in a collection (e.g., arrays, lists, or
other iterable objects).
o On each iteration, line holds the value of the current string in the array.
o The loop moves to the next element until all elements are processed.
o Each element in this array will hold a substring extracted from line.
3. = (Assignment Operator)
o line is a string variable that contains text (e.g., a single line from a file).
o This text will be split into smaller parts based on the given delimiter (" | ").
5. .Split(" | ") (Method Call)
o It splits the line into an array of substrings based on a given delimiter (" |
").
o Each part before or after " | " becomes an element in the parts array.
if (parts.Length == 2) {
1. if (Conditional Statement)
2. (parts.Length == 2) (Condition)
o Typically, this block processes the extracted username and password from
parts[0] and parts[1].
3. = (Assignment Operator)
o Assigns the value on the right (parts[0]) to the variable storedUsername.
o This is the name of the variable that will store the hashed password.
3. = (Assignment Operator)
o Assigns the value from the right-hand side (parts[1]) to the variable
storedHashedPassword.
Explanation:
1. if (Conditional Statement)
o Ensures that both conditions must be true for the entire if condition to be
true.
return RedirectToAction("Success");
1. return (Keyword)
o This is a built-in ASP.NET Core MVC method that redirects the user to a
different action method within the same controller.
o This means that after form submission, the user is redirected to the
Success action, which likely renders a confirmation page.