Food Ordering System Part 12 | User Registration in ASP.NET Core MVC

 


Secure your application in Part 12 of our Online Food Ordering System series! Today, we dive into Customer Registration in ASP.NET Core MVC. Learn how to build a professional Sign-Up form, validate user input, and save customer data to the database using Entity Framework Core. We cover everything from creating the AccountController to handling password hashing and user roles. This tutorial is essential for anyone building a functional C# Web Application with a secure member area. Join us and start building your E-commerce Authentication system today!

In Part 12, we begin the essential process of User Authentication. Before a customer can place an order, they need a way to create an account. The Register GET action is the first step in this journey—it is the "entry point" that serves the sign-up form to your users.

Step-by-Step Code Explanation

  1. [HttpGet] Attribute: This decorator tells ASP.NET Core that this method should only handle GET requests. This happens when a user types the URL into their browser or clicks a "Sign Up" link. It is the "Request for the Page."

  2. public IActionResult Register(): This is the action method name. By convention, ASP.NET Core will look for a view file named Register.cshtml inside the Views/Account folder.

  3. return View();: This is a simple but powerful command. It tells the server to render the HTML registration form and send it back to the customer's browser so they can start entering their details.

ACCOUNTCONTROLLER.CS (GET ACTION)
[HttpGet]
public IActionResult Register()
{
    return View();
}

We are setting up the backbone of our registration system. The RegisterViewModel is a specialized class designed specifically for the Sign-Up page. It acts as a bridge, carrying only the necessary data from the user's browser to the server while ensuring that data is valid and secure.

Step-by-Step Code Explanation

  1. Data Annotations ([Required], [EmailAddress]): These are validation attributes. They automatically check if the user has filled in the field and if the email format is correct (e.g., contains @ and .com).

  2. Password Security:

    • [StringLength(100, MinimumLength = 6)]: This forces the user to create a password at least 6 characters long, which is a standard security practice.

    • [DataType(DataType.Password)]: This ensures that when the user types their password, it appears as dots or asterisks on the screen.

  3. Password Comparison ([Compare("Password")]): This is a powerful attribute for the ConfirmPassword field. It automatically checks if the second password matches the first one. If they don't match, the system will show an error.

  4. Customer Details: We include fields like FullName, Address, and Phone so we can store delivery information directly when the user creates their account.

MODELS/VIEWMODELS/REGISTERVIEWMODEL.CS
using System.ComponentModel.DataAnnotations;

namespace FoodOrderingSystem.Models.ViewModels
{
    public class RegisterViewModel
    {
        [Required]
        [StringLength(50)]
        public string Username { get; set; }

        [Required]
        [EmailAddress]
        public string Email { get; set; }

        [Required]
        [StringLength(100, MinimumLength = 6)]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Compare("Password")]
        public string ConfirmPassword { get; set; }

        public string FullName { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
    }
}

We are building the interface where our customers will interact with the system to join our platform. This Register View is designed with Bootstrap 5 to be clean, responsive, and user-friendly, ensuring a smooth sign-up experience.


Step-by-Step Code Explanation

  1. The Model Connection: @model RegisterViewModel connects this HTML page to the specialized class we created earlier. This allows the page to "know" which fields (Username, Email, etc.) to expect.

  2. Tag Helpers (asp-for): Instead of standard HTML, we use ASP.NET Core Tag Helpers. These automatically generate the correct id, name, and validation attributes for each input field based on our ViewModel.

  3. Form Validation:

    • asp-validation-summary: This shows a list of errors at the top if the registration fails (e.g., if the user leaves a required field blank).

    • asp-validation-for: These small span tags display error messages directly under each specific input box in real-time.

  4. Layout & UI:

    • col-md-5 and shadow: These Bootstrap classes center the registration box and give it a modern "floating" appearance.

    • w-100: This makes the "Register" button span the full width of the card, making it a clear and easy target for users to click.

  5. User Navigation: At the bottom, we include a quick link to the Login page for users who might have clicked "Register" by mistake but already have an account.

VIEWS/ACCOUNT/REGISTER.CSHTML
@model FoodOrderingSystem.Models.ViewModels.RegisterViewModel
@{
    ViewData["Title"] = "Register";
}

<div class="container my-5">
    <div class="row justify-content-center">
        <div class="col-md-5">
            <div class="card shadow">
                <div class="card-body">
                    <h3 class="text-center mb-4">Create Account</h3>
                    <form asp-action="Register" method="post">
                        <div asp-validation-summary="ModelOnly" class="text-danger"></div>

                        <div class="mb-3">
                            <label asp-for="Username" class="form-label"></label>
                            <input asp-for="Username" class="form-control" />
                            <span asp-validation-for="Username" class="text-danger"></span>
                        </div>

                        <div class="mb-3">
                            <label asp-for="Email" class="form-label"></label>
                            <input asp-for="Email" class="form-control" />
                            <span asp-validation-for="Email" class="text-danger"></span>
                        </div>

                        <div class="mb-3">
                            <label asp-for="Password" class="form-label"></label>
                            <input asp-for="Password" class="form-control" />
                            <span asp-validation-for="Password" class="text-danger"></span>
                        </div>

                        <div class="mb-3">
                            <label asp-for="ConfirmPassword" class="form-label"></label>
                            <input asp-for="ConfirmPassword" class="form-control" />
                            <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
                        </div>

                        <div class="mb-3">
                            <label asp-for="FullName" class="form-label"></label>
                            <input asp-for="FullName" class="form-control" />
                        </div>

                        <div class="mb-3">
                            <label asp-for="Address" class="form-label"></label>
                            <input asp-for="Address" class="form-control" />
                        </div>

                        <div class="mb-3">
                            <label asp-for="Phone" class="form-label"></label>
                            <input asp-for="Phone" class="form-control" />
                        </div>

                        <button type="submit" class="btn btn-primary w-100">Register</button>
                    </form>

                    <hr />
                    <p class="text-center">Already have an account? <a href="#">Login</a></p>
                </div>
            </div>
        </div>
    </div>
</div>

We are completing the registration cycle. While the previous part showed the form, this HttpPost Action is the "engine" that takes the data entered by the customer and permanently saves it into your SQL database.

Step-by-Step Code Explanation

  1. [HttpPost] Attribute: This tells the controller that this method is only for receiving data submitted from a form. It’s the "Save" phase of the process.

  2. ModelState.IsValid: This is a crucial security check. It looks back at the RegisterViewModel we created. If the user missed a required field or the passwords don't match, this will be false, and the user will see error messages.

  3. Mapping Data: We create a new User object (which represents your database table) and transfer the data from the model (the form) into it.

  4. Database Storage:

    • _context.Users.Add(user): This tells Entity Framework to prepare the new user for the database.

    • _context.SaveChanges(): This is the final "Commit." It executes the SQL command to insert the row into your table.

  5. Redirection: Once the user is successfully saved, we use RedirectToAction("Login") to send them to the login page so they can sign in for the first time.

  6. The "Fallback": If the data was invalid, the code returns View(model). This sends the user back to the form with their typed data still there, along with the error messages.

ACCOUNTCONTROLLER.CS (POST ACTION)
[HttpPost]
public IActionResult Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new User
        {
            Username = model.Username,
            Email = model.Email,
            Password = model.Password, // In production, hash this!
            FullName = model.FullName,
            Address = model.Address,
            Phone = model.Phone
        };

        _context.Users.Add(user);
        _context.SaveChanges();

        return RedirectToAction("#");
    }

    return View(model);
}

Comments