স্বাগতম! আজকের লেকচারে আমরা 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 কোড দেখতে পায় না।
- প্রথমে Server-side-এ Razor Engine Code Block এবং Expression গুলো এক্সিকিউট করে ভ্যালু বের করে।
- এরপর সেই ভ্যালুগুলো HTML ট্যাগের ভেতর বসিয়ে একটি সম্পূর্ণ Plain HTML পেজ তৈরি করে।
- এই Plain HTML পেজটি HTTP Response হিসেবে Browser-এ পাঠানো হয়।
- সবশেষে 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:
- Dumb Views: View-কে যতটা সম্ভব “বোকা” (লজিকহীন) রাখতে হবে। View-এর ভেতর কোনো ক্যালকুলেশন বা লজিক (যেমন- বয়স বের করা) থাকবে না।
- 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 করা অনেক সহজ হয়।