স্বাগতম! আজকের লেকচারে আমরা ASP.NET Core-এর Razor Syntax ব্যবহার করে কীভাবে একটি View-এর ভেতর C-sharp এবং HTML কোড একসাথে লিখতে হয়, তা নিয়ে বিস্তারিত আলোচনা করব।

শুরুতেই চলুন পুরো লেকচারের একটি সংক্ষিপ্ত সামারি দেখে নিই।

📝 লেকচার সামারি (Quick Revision List)

  • Razor Engine: এটি ASP.NET Core-এর View Engine, যা HTML-এর ভেতর C-sharp কোড লেখার সুযোগ দেয়।
  • Razor Code Block (@{ … }): এর ভেতর যেকোনো ভ্যালিড C-sharp স্টেটমেন্ট (যেমন- ভেরিয়েবল ডিক্লেয়ারেশন, লজিক) লেখা যায়।
  • Razor Expression (@variableName): এটি ব্যবহার করে C-sharp ভেরিয়েবলের ভ্যালু সরাসরি HTML-এর ভেতর প্রিন্ট করা হয়।
  • Execution Flow: View-এর C-sharp কোড আগে Server-side-এ এক্সিকিউট হয়। এরপর সেই ডাটা HTML-এ বসে plain HTML হিসেবে Client-side (Browser)-এ রেসপন্স যায়।
  • Namespace Import (@using): View-এ কোনো Model ক্লাস ব্যবহার করতে হলে ফাইলের শুরুতে @using দিয়ে Namespace ইমপোর্ট করতে হয়।
  • Variable Scope: একটি Razor Code Block-এ তৈরি করা ভেরিয়েবল একই View-এর নিচের অন্যান্য Code Block বা Expression-এ ব্যবহার করা যায়।
  • Architectural Rule: View-তে খুব বেশি C-sharp কোড (১০ লাইনের বেশি) লেখা উচিত নয়। লজিকের কাজ Controller-এর হাতে ছেড়ে দেওয়া বেস্ট প্র্যাকটিস।

📖 Comprehensive Breakdown (বিস্তারিত বিশ্লেষণ)

১. Razor Code Blocks & Expressions (Importance: 10/10)

কী এবং কেন (What & Why): View-তে ডাইনামিক ডাটা দেখানোর জন্য আমাদের HTML-এর সাথে C-sharp কোড মেশানোর প্রয়োজন হয়। এর জন্য ASP.NET Core Razor নামের একটি View Engine ব্যবহার করে। Razor-এর স্পেশাল ক্যারেক্টার হলো @ (At symbol)।

  • Razor Code Block (@{ … }): এর ভেতরে আপনি মেথডের মতই C-sharp কোড লিখতে পারবেন। এখানে লজিক বিল্ড করা হয়।
  • Razor Expression (@): এটি দিয়ে কোনো লজিক লেখা হয় না, বরং জেনারেট হওয়া ডাটা বা ভেরিয়েবল সরাসরি HTML-এ প্রিন্ট করা হয়।

Code Implementation:

@{
    // এটি Razor Code Block. এখানে C-sharp কোড সার্ভারে এক্সিকিউট হবে।
    string appTitle = "Welcome to My App";
}
 
<!-- এটি Razor Expression. appTitle-এর ভ্যালু এখানে প্রিন্ট হবে -->
<title>@appTitle</title>
 

২. Server-side vs Client-side Execution Flow (Importance: 10/10)

কীভাবে কাজ করে: যখন একটি View কল করা হয়, তখন Browser কখনোই C-sharp কোড দেখতে পায় না।

  1. প্রথমে Server-side-এ Razor Engine Code Block এবং Expression গুলো এক্সিকিউট করে ভ্যালু বের করে।
  2. এরপর সেই ভ্যালুগুলো HTML ট্যাগের ভেতর বসিয়ে একটি সম্পূর্ণ Plain HTML পেজ তৈরি করে।
  3. এই Plain HTML পেজটি HTTP Response হিসেবে Browser-এ পাঠানো হয়।
  4. সবশেষে Browser সেই HTML কোড এক্সিকিউট করে ইউজারকে প্রদর্শন করে।

Visual Studio Shortcut: লেকচারার দেখিয়েছেন যে, ব্রাউজারে অ্যাপ রান করার পর Ctrl + Shift + I চাপলে Developer Tools-এর Network Tab ওপেন হবে। সেখানে Request-এ ক্লিক করে Response অপশনে গেলে আপনি দেখতে পাবেন যে সার্ভার থেকে শুধুমাত্র Plain HTML এসেছে, কোনো @ বা C-sharp কোড আসেনি।

৩. Default Routing Configuration (Importance: 8/10)

যাতে প্রজেক্ট রান করার সাথে সাথেই HomeController-এর Index অ্যাকশনটি কল হয়, তার জন্য Default Route সেট করা যায়।

Code Implementation (Controller):

public class HomeController : Controller
{
    // [Route("/")] দিলে শুধু "localhost:port" তেই এই পেজটি রান হবে
    [Route("/")] 
    [Route("home")]
    public IActionResult Index()
    {
        return View();
    }
}
 

৪. Using Models Inside Views (Importance: 9/10)

লেকচারে একটি Person Model ক্লাস তৈরি করে সেটির ডাটা View-তে দেখানোর প্রক্রিয়া বোঝানো হয়েছে।

Model Class Setup:

namespace MyApp.Models
{
    public class Person
    {
        public string Name { get; set; }
        public DateTime DateOfBirth { get; set; }
    }
}
 

View-তে Model ব্যবহার এবং Age Calculation: View ফাইলে Model ক্লাসটি ব্যবহার করার জন্য ফাইলের একদম শুরুতে @using কিওয়ার্ড দিয়ে Namespace ইমপোর্ট করতে হয়।

@using MyApp.Models
 
@{
    // প্রথম Code Block: অবজেক্ট তৈরি এবং ইনিশিয়ালাইজেশন
    Person person = new Person()
    {
        Name = "Hasib",
        DateOfBirth = new DateTime(2000, 1, 1) // লেকচারারের ২০০০ সালের উদাহরণ
    };
}
 
<!-- Expression ব্যবহার করে ডাটা প্রিন্ট -->
<h1>Hello, @person.Name!</h1>
 
@{
    // দ্বিতীয় Code Block: Age ক্যালকুলেশন
    // Scope Rule: প্রথম ব্লকের 'person' ভেরিয়েবলটি এখানে অ্যাক্সেস করা যাচ্ছে।
    TimeSpan timeSpan = DateTime.Now - person.DateOfBirth;
    double age = Math.Round(timeSpan.TotalDays / 365.25);
}
 
<!-- Age প্রিন্ট করা এবং সাথে Static HTML Text -->
<h2>You are @age years old.</h2>
 

কেন (Why): এই উদাহরণের মাধ্যমে বোঝানো হয়েছে যে, একটি View-এর ভেতর একাধিক Razor Block থাকতে পারে এবং তাদের মধ্যে Variable Scope শেয়ার হয়।

৫. Architectural Quick Facts (Importance: 9/10)

লেকচারের শেষে কিছু অত্যন্ত গুরুত্বপূর্ণ আর্কিটেকচারাল রুলস বলা হয়েছে:

  • Rule of 10 Lines: View-এর কাজ শুধু ডাটা দেখানো (Presentation Logic)। View-তে যদি আপনাকে ১০ লাইনের বেশি C-sharp কোড লিখতে হয়, তবে বুঝতে হবে আপনার ডিজাইনে ভুল আছে। এই লজিকগুলো Controller-এ নিয়ে যাওয়া উচিত।
  • View Model vs Business Model: View কখনোই সরাসরি Business Model-কে কল করে ডাটাবেস অপারেশন চালাবে না। View শুধুমাত্র Controller থেকে পাঠানো ViewModel রিসিভ করবে এবং ডাটা দেখাবে।

🌟 Best Practices & .NET 10 Updates

লেকচারে View-এর ভেতর Model অবজেক্ট তৈরি (new Person()) এবং বয়স ক্যালকুলেশনের (DateTime.Now - …) যে পদ্ধতি দেখানো হয়েছে, সেটি শুধুমাত্র “Razor কীভাবে কাজ করে” তা বোঝানোর জন্য। রিয়েল-ওয়ার্ল্ড প্রজেক্টে এটি একটি Anti-pattern (খারাপ প্র্যাকটিস)

Best Practices:

  1. Dumb Views: View-কে যতটা সম্ভব “বোকা” (লজিকহীন) রাখতে হবে। View-এর ভেতর কোনো ক্যালকুলেশন বা লজিক (যেমন- বয়স বের করা) থাকবে না।
  2. Controller’s Responsibility: Controller ক্যালকুলেশন করে একটি প্রস্তুত ডাটা (ViewModel) View-তে পাঠাবে। View শুধু সেটি লুপ বা এক্সপ্রেশন দিয়ে প্রিন্ট করবে।

.NET 10 Modern Approach (Strongly Typed View): আধুনিক .NET-এ আমরা নিচের মতো করে Controller থেকে ViewModel পাস করি।

Step 1: Controller (Logic goes here)

public class HomeController : Controller
{
    [Route("/")]
    public IActionResult Index()
    {
        // Controller লজিক হ্যান্ডেল করবে এবং অবজেক্ট তৈরি করবে
        var person = new Person()
        {
            Name = "Hasib",
            DateOfBirth = new DateTime(2000, 1, 1)
        };
 
        // View-এর কাছে Model ডাটা পাঠিয়ে দেওয়া হলো
        return View(person); 
    }
}
 

Step 2: View (Only Presentation goes here)

<!-- View-এর শুরুতে Strongly Typed Model ডিক্লেয়ার করা -->
@model MyApp.Models.Person
 
<!-- View-এর ভেতর কোনো Code Block বা লজিক নেই। একদম ক্লিন! -->
<h1>Hello, @Model.Name!</h1>
 
<!-- .NET 10 এ Date formatting অনেক সহজ -->
<h2>Your birth year is @Model.DateOfBirth.ToString("yyyy").</h2>
 

Why this is smarter: এই পদ্ধতিতে Separation of Concerns বজায় থাকে। Controller তার লজিকের কাজ করে এবং View শুধু UI রেন্ডার করার কাজ করে। এতে কোড মেইনটেইন এবং Unit Test করা অনেক সহজ হয়।