হাসিব, চলো তোমার কোর্সের ৯৭ নম্বর লেকচারটি নিয়ে বিস্তারিত আলোচনা করি। আউটলাইন অনুযায়ী এটি (Section 8: Views - MVC Architecture Pattern) এর অংশ, যার শিরোনাম “Strongly Typed Views - Part 1”।
আগের লেকচারগুলোতে আমরা দেখেছি কীভাবে ViewData এবং ViewBag ব্যবহার করে Controller থেকে View-তে ডেটা পাঠাতে হয়। কিন্তু সেখানে টাইপকাস্টিং এবং Magic Strings-এর মতো কিছু সমস্যা ছিল। এই লেকচারে ইনস্ট্রাক্টর সেই সমস্যার একটি আধুনিক ও স্ট্যান্ডার্ড সমাধান নিয়ে আলোচনা করেছেন, যাকে বলা হয় Strongly Typed Views।
নিচে পুরো লেকচারটির বিস্তারিত ব্রেকডাউন দেওয়া হলো:
📝 Summary (সারসংক্ষেপ)
- What is Strongly Typed View? যখন কোনো Razor View-কে একটি নির্দিষ্ট Model Class-এর সাথে টাইটলি বাইন্ড (Tightly Bind) বা যুক্ত করা হয়, তখন তাকে Strongly Typed View বলে।
- How to declare: View-এর একদম উপরে @model (ছোট হাতের ‘m’) ডিরেক্টিভ ব্যবহার করে মডেলের ডেটা টাইপ বলে দিতে হয়।
- How to send data: Controller-এ ViewData বা ViewBag ব্যবহার না করে, return View(modelObject); এর মাধ্যমে সরাসরি মডেলটি পাঠাতে হয়।
- How to read data: View-তে ডেটা রিড করার জন্য @Model (বড় হাতের ‘M’) প্রোপার্টি ব্যবহার করতে হয়।
- The Benefit: এর সবচেয়ে বড় সুবিধা হলো, কোনো টাইপকাস্টিংয়ের প্রয়োজন হয় না এবং কোড লেখার সময় Visual Studio-তে ১০০% Intellisense (Auto-completion) সাপোর্ট পাওয়া যায়।
📌 The Concept: Strongly Typed Views [Priority: 10/10]
Why do we need this? (কেন দরকার?) আগের লেকচারে যখন আমরা ViewBag.People ব্যবহার করছিলাম, তখন লুপের ভেতরে @person. লিখলে কোনো প্রোপার্টির নাম সাজেশন হিসেবে আসত না। কারণ View জানতই না যে ওই ডেটার আসল টাইপ কী।
Strongly Typed View এই সমস্যাটি সমাধান করে। এটি View-কে আগে থেকেই জানিয়ে দেয় যে, “তুমি Controller থেকে একটি নির্দিষ্ট টাইপের ডেটা (যেমন- List) রিসিভ করতে যাচ্ছ।” এর ফলে কম্পাইলার ওই ডেটার সব প্রোপার্টি চিনে ফেলে এবং ডেভেলপারকে কোড লিখতে সাহায্য করে।
📌 Step 1: Sending Data from Controller [Priority: 10/10]
প্রথম কাজ হলো Controller থেকে ডেটাটি পাঠানো। এখানে ViewData বা ViewBag এর কোনো কাজ নেই। আমরা সরাসরি ডেটাটিকে View() মেথডের ভেতরে পাস করে দেব।
// Controllers/HomeController.cs
using Microsoft.AspNetCore.Mvc;
using MyWebApp.Models;
public class HomeController : Controller
{
public IActionResult Index()
{
// ১. ডাটাবেজ বা অন্য কোনো সোর্স থেকে ডেটা রেডি করা
List<Person> people = new List<Person>
{
new Person { Name = "Hasib", Gender = "Male" },
new Person { Name = "John", Gender = "Male" }
};
// ২. View-তে সরাসরি Model (people কালেকশন) পাঠানো
// এটিই হলো মডেল সাপ্লাই দেওয়ার স্ট্যান্ডার্ড পদ্ধতি
return View(people);
// নোট: যদি View এর নাম আলাদা হয়, তবে এভাবে লিখতে হয়:
// return View("EmployeeList", people);
}
}
ইনস্ট্রাক্টরের অ্যানালজি (Analogy): তুমি একটি ফলের ঝুড়ি (Basket) নিয়ে তাতে ফল (Data) সাজিয়ে তোমার সামনের মানুষটিকে (View) দিয়ে দিচ্ছ। Controller এখানে হুবহু সেই কাজটিই করছে।
📌 Step 2: Receiving & Declaring the Model in View [Priority: 10/10]
Controller থেকে ডেটা পাঠানোর পর, View-কে জানাতে হবে যে সে কী ধরনের ডেটা রিসিভ করছে। এর জন্য View ফাইলের একদম প্রথম লাইনে @model (ছোট হাতের m) ডিরেক্টিভ ব্যবহার করতে হয়।
<!-- Views/Home/Index.cshtml -->
<!-- ১. Model ডিক্লেয়ারেশন (ছোট হাতের 'm') -->
<!-- ইনস্ট্রাক্টর বলেছেন List<Person> বা IEnumerable<Person> যেকোনোটি ব্যবহার করা যায় -->
@model IEnumerable<MyWebApp.Models.Person>
<!-- ২. ডেটা রিড করা (বড় হাতের 'M') -->
<div class="page-content">
<!-- Model এখন আর null বা object নয়, এটি সরাসরি একটি IEnumerable<Person> -->
@foreach (var person in Model)
{
<div class="box float-left w-50">
<!-- ৩. Intellisense এর সুবিধা -->
<!-- @person. লেখার সাথে সাথেই Name, Gender সাজেশন হিসেবে আসবে -->
<h3>@person.Name</h3>
<p>Gender: @person.Gender</p>
</div>
}
</div>
📌 @model vs @Model (The Tricky Part) [Priority: 9/10]
নতুন ডেভেলপাররা এখানে খুব সহজেই কনফিউজড হয়ে যায়। এই দুটির পার্থক্য মনে রাখা জরুরি:
- @model (Lowercase ‘m’): এটি হলো একটি Directive (নির্দেশনা)। এটি সব সময় View ফাইলের একদম উপরে বসে এবং এর কাজ হলো শুধু ডেটা টাইপটি বলে দেওয়া। এটি কোনো ডেটা প্রিন্ট করে না। উদাহরণ: @model IEnumerable
- @Model (Uppercase ‘M’): এটি হলো View ক্লাসের একটি বিল্ট-ইন Property (যার মধ্যে আসল ডেটাটি থাকে)। Controller থেকে তুমি যে অবজেক্টটি পাঠিয়েছ, তা এই @Model-এর ভেতরেই থাকে। একে তুমি View-এর যেকোনো জায়গায় ব্যবহার করতে পারবে। উদাহরণ: @foreach (var p in Model)
⭐ Best Practices & Modern .NET 10 Context
Strongly Typed Views-ই হলো আধুনিক MVC অ্যাপ্লিকেশনের Gold Standard। .NET Core 1.0 থেকে শুরু করে .NET 10 পর্যন্ত, ডেটা পাস করার জন্য এটিই সবচেয়ে রিকমেন্ডেড পদ্ধতি।
- Always use IEnumerable for collections: View-এর ডিক্লেয়ারেশনে @model List না লিখে @model IEnumerable লেখা ভালো প্র্যাকটিস। কারণ IEnumerable হলো List, Array, Collection সবকিছুর প্যারেন্ট ইন্টারফেস। এর ফলে তুমি Controller থেকে List পাঠাও বা Array পাঠাও, View তা রিসিভ করতে পারবে।
- Namespace Management: প্রতিটি View ফাইলে MyWebApp.Models.Person এভাবে পুরো পাথ না লিখে, _ViewImports.cshtml ফাইলে using MyWebApp.Models; গ্লোবালি অ্যাড করে নেওয়া ভালো (যা এই কোর্সের ১০০ নম্বর লেকচারে তুমি শিখবে)।
- ViewModels over Domain Models: রিয়েল-ওয়ার্ল্ড প্রজেক্টে, ডাটাবেজের আসল Model (যেমন Person) সরাসরি View-তে পাঠানো হয় না। এর বদলে একটি ViewModel (যেমন PersonListViewModel) তৈরি করে শুধু View-এর জন্য প্রয়োজনীয় ডেটাগুলো পাঠানো হয়। এটি ডেটা সিকিউরিটি এবং UI কাস্টমাইজেশনের জন্য অনেক বেশি স্ট্যান্ডার্ড।