আজকের লেকচারে স্বাগতম!

কোথায় আছি আমরা? আপনি বর্তমানে Section 25: Identity-তে আছেন। গত লেকচারে আমরা Identity-র জন্য ডাটাবেস টেবিলের গঠন বা Entity Classes তৈরি করা শিখেছিলাম। আজ আমরা শিখবো কীভাবে একজন নতুন ইউজারকে সিস্টেমে যুক্ত করার জন্য Register View এবং Controller তৈরি করতে হয়। এটি ইউজার রেজিস্ট্রেশন প্রক্রিয়ার প্রথম ধাপ। চলুন শুরু করি!


📝 Quick Summary for Revision

ভবিষ্যতে দ্রুত রিভিশন দেওয়ার জন্য পুরো লেকচারের মূল বিষয়গুলো নিচে লিস্ট করা হলো:

  • Create DTO (View Model): ইউজারের কাছ থেকে ইনপুট নেওয়ার জন্য RegisterDTO তৈরি করা এবং તેમાં Data Annotations যুক্ত করা।
  • ViewImports Setup: View-তে DTO ক্লাসের namespace গ্লোবালি ইম্পোর্ট করা।
  • Create Register View: Razor view তৈরি করে Strongly-typed Tag Helpers (asp-for) ব্যবহার করে ফর্ম ডিজাইন করা এবং Client-side validation এনাবল করা।
  • AccountController Setup: Register অ্যাকশনের জন্য HTTP GET (ফর্ম দেখানোর জন্য) এবং HTTP POST (ডেটা রিসিভ করার জন্য) মেথড তৈরি করা।
  • Layout Update: _Layout.cshtml-এ Register লিংকের URL ঠিক করে দেওয়া।

🧠 Comprehensive Breakdown

এখানে লেকচারের প্রতিটি বিষয় বিস্তারিতভাবে এবং ধাপে ধাপে ব্যাখ্যা করা হলো:

১. Creating the Register DTO / View Model (Priority: 9/10)

ইউজারের কাছ থেকে ডেটা রিসিভ করে View থেকে Controller-এ ট্রান্সফার করার জন্য একটি DTO (Data Transfer Object) বা View Model ক্লাস তৈরি করতে হয়।

Why do this? আমরা সরাসরি আমাদের Entity ক্লাস (ApplicationUser) View-তে পাঠাই না, কারণ Entity ক্লাসে অনেক সেনসিটিভ ডেটা থাকতে পারে। তার বদলে আমরা শুধু ততটুকুই প্রপার্টি রাখি, যতটুকু ইউজারের কাছ থেকে ফর্মে নিতে চাই।

💻 Code Implementation: Core প্রজেক্টের DTO ফোল্ডারে RegisterDTO.cs নামে একটি ক্লাস তৈরি করুন। এখানে আমরা Data Annotations ব্যবহার করে ভ্যালিডেশন রুলস সেট করবো।

using System.ComponentModel.DataAnnotations;
 
namespace ContactManager.Core.DTO
{
    public class RegisterDTO
    {
        [Required(ErrorMessage = "Name can't be blank")]
        public string PersonName { get; set; }
 
        [Required(ErrorMessage = "Email can't be blank")]
        [EmailAddress(ErrorMessage = "Email should be in a proper valid email format")]
        public string Email { get; set; }
 
        [Required(ErrorMessage = "Phone number can't be blank")]
        [RegularExpression("^[0-9]*$", ErrorMessage = "Phone number should contain numbers only")]
        public string PhoneNumber { get; set; }
 
        [Required(ErrorMessage = "Password can't be blank")]
        [DataType(DataType.Password)] // এটি View-তে input type="password" তৈরি করবে
        public string Password { get; set; }
 
        [Required(ErrorMessage = "Confirm Password can't be blank")]
        [DataType(DataType.Password)]
        [Compare("Password", ErrorMessage = "Password and confirm password do not match")] // আধুনিক আপডেট: Compare অ্যাট্রিবিউট ব্যবহার করা ভালো
        public string ConfirmPassword { get; set; }
    }
}
 

২. Setting up _ViewImports.cshtml (Priority: 5/10)

View-তে আমাদের RegisterDTO ব্যবহার করতে হবে। বারবার পুরো namespace না লিখে, গ্লোবালি এটি ইম্পোর্ট করে রাখা ভালো।

  • Views/_ViewImports.cshtml ফাইলে গিয়ে নিচের লাইনটি যুক্ত করুন: @using ContactManager.Core.DTO

৩. Building the Register View (UI) (Priority: 10/10)

এখন আমরা আসল ফর্মটি তৈরি করবো। Views ফোল্ডারে Account নামে একটি নতুন ফোল্ডার তৈরি করে সেখানে Register.cshtml ফাইলটি অ্যাড করুন।

Why Strongly Typed? আমরা @model RegisterDTO ডিক্লেয়ার করার মাধ্যমে View-কে Strongly-typed করছি। এর ফলে আমরা Tag Helpers (যেমন: asp-for) ব্যবহার করতে পারবো, যা অটোমেটিকভাবে HTML ট্যাগ জেনারেট করবে এবং টাইপিং মিস্টেক রোধ করবে।

💻 Code Implementation:

@model RegisterDTO
 
@{
    ViewBag.Title = "Register";
}
 
<div class="text-large">Register</div>
<form asp-controller="Account" asp-action="Register" method="post">
    
    <div>
        <label asp-for="PersonName"></label>
        <input asp-for="PersonName" class="form-control" />
        <span asp-validation-for="PersonName" class="text-danger"></span>
    </div>
 
    <div>
        <label asp-for="Email"></label>
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
    </div>
 
    <div>
        <label asp-for="Password"></label>
        <input asp-for="Password" class="form-control" />
        <span asp-validation-for="Password" class="text-danger"></span>
    </div>
 
    <button type="submit" class="btn btn-primary">Register</button>
 
    <div asp-validation-summary="All" class="text-danger"></div>
</form>
 
@section Scripts {
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.12/jquery.validate.unobtrusive.min.js"></script>
}
 

(নোট: লেকচারার অন্য ফাইল থেকে স্ক্রিপ্ট কপি করেছেন, তবে আধুনিক প্র্যাকটিসে _ValidationScriptsPartial.cshtml বা সরাসরি CDN লিংক ব্যবহার করা হয় যা আমি উপরে দেখিয়েছি)

৪. Creating the AccountController (Priority: 10/10)

ইউজার ফর্মটি দেখতে চাইলে বা ফিলাপ করে সাবমিট করলে তা হ্যান্ডেল করার জন্য Controller প্রয়োজন। Controllers ফোল্ডারে AccountController.cs তৈরি করুন।

💻 Code Implementation:

using ContactManager.Core.DTO;
using Microsoft.AspNetCore.Mvc;
 
namespace ContactManager.UI.Controllers
{
    [Route("[controller]/[action]")]
    public class AccountController : Controller
    {
        // 1. HTTP GET: ফর্মটি ব্রাউজারে দেখানোর জন্য
        [HttpGet]
        public IActionResult Register()
        {
            return View();
        }
 
        // 2. HTTP POST: ইউজারের সাবমিট করা ডেটা রিসিভ করার জন্য
        [HttpPost]
        public IActionResult Register(RegisterDTO registerDTO)
        {
            // Update: লেকচারার এটি দেখাননি, কিন্তু ডেটা প্রসেস করার আগে Model ভ্যালিডেশন চেক করা মাস্ট!
            if (!ModelState.IsValid)
            {
                ViewBag.Errors = ModelState.Values.SelectMany(temp => temp.Errors).Select(temp => temp.ErrorMessage);
                return View(registerDTO); // Error থাকলে ফর্মে ফেরত পাঠাবে
            }
 
            // এখানে পরবর্তীতে Identity Database-এ সেভ করার কোড বসবে
 
            // সফলভাবে রেজিস্ট্রেশন হলে Persons/Index পেজে রিডাইরেক্ট করবে
            return RedirectToAction("Index", "Persons");
        }
    }
}
 

৫. Updating the Layout (Priority: 4/10)

সবশেষে, _Layout.cshtml ফাইলে গিয়ে Register বাটনের লিংকটি ঠিক করে দিতে হবে যাতে ইউজার ক্লিক করলেই পেজটি ওপেন হয়।

<a asp-controller="Account" asp-action="Register">Register</a>
 

🌟 Best Practices

  • Always Check ModelState in POST Action: লেকচারার শুধু ডেটা রিসিভ করে রিডাইরেক্ট করেছেন, কিন্তু সিকিউরিটির জন্য সবসময় [HttpPost] মেথডে if (!ModelState.IsValid) চেক করতে হবে। ক্লায়েন্ট-সাইড ভ্যালিডেশন (জাভাস্ক্রিপ্ট) বাইপাস করা সম্ভব, তাই সার্ভার-সাইডে (Controller-এ) ভ্যালিডেশন চেক করা বাধ্যতামূলক।
  • Use [Compare] Attribute: পাসওয়ার্ড এবং কনফার্ম পাসওয়ার্ড মিলছে কিনা তা চেক করার জন্য RegisterDTO-তে [Compare("Password")] Data Annotation ব্যবহার করা সবচেয়ে স্ট্যান্ডার্ড প্র্যাকটিস।
  • Validation Scripts Partial: View-এর শেষে বারবার স্ক্রিপ্ট লিংক কপি-পেস্ট না করে, ASP.NET Core-এ সাধারণত একটি _ValidationScriptsPartial.cshtml ফাইল থাকে। @await Html.PartialAsync("_ValidationScriptsPartial") কল করে দিলেই কোড অনেক ক্লিন থাকে।

পরবর্তী লেকচারে আমরা শিখবো কীভাবে এই POST মেথড থেকে ডেটা নিয়ে সত্যি সত্যিই Identity ডাটাবেসে ইউজার সেভ করতে হয়!