হাসিব, চলো তোমার কোর্সের ৯৭ নম্বর লেকচারটি নিয়ে বিস্তারিত আলোচনা করি। আউটলাইন অনুযায়ী এটি (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]

নতুন ডেভেলপাররা এখানে খুব সহজেই কনফিউজড হয়ে যায়। এই দুটির পার্থক্য মনে রাখা জরুরি:

  1. @model (Lowercase ‘m’): এটি হলো একটি Directive (নির্দেশনা)। এটি সব সময় View ফাইলের একদম উপরে বসে এবং এর কাজ হলো শুধু ডেটা টাইপটি বলে দেওয়া। এটি কোনো ডেটা প্রিন্ট করে না। উদাহরণ: @model IEnumerable
  2. @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 পর্যন্ত, ডেটা পাস করার জন্য এটিই সবচেয়ে রিকমেন্ডেড পদ্ধতি।

  1. Always use IEnumerable for collections: View-এর ডিক্লেয়ারেশনে @model List না লিখে @model IEnumerable লেখা ভালো প্র্যাকটিস। কারণ IEnumerable হলো List, Array, Collection সবকিছুর প্যারেন্ট ইন্টারফেস। এর ফলে তুমি Controller থেকে List পাঠাও বা Array পাঠাও, View তা রিসিভ করতে পারবে।
  2. Namespace Management: প্রতিটি View ফাইলে MyWebApp.Models.Person এভাবে পুরো পাথ না লিখে, _ViewImports.cshtml ফাইলে using MyWebApp.Models; গ্লোবালি অ্যাড করে নেওয়া ভালো (যা এই কোর্সের ১০০ নম্বর লেকচারে তুমি শিখবে)।
  3. ViewModels over Domain Models: রিয়েল-ওয়ার্ল্ড প্রজেক্টে, ডাটাবেজের আসল Model (যেমন Person) সরাসরি View-তে পাঠানো হয় না। এর বদলে একটি ViewModel (যেমন PersonListViewModel) তৈরি করে শুধু View-এর জন্য প্রয়োজনীয় ডেটাগুলো পাঠানো হয়। এটি ডেটা সিকিউরিটি এবং UI কাস্টমাইজেশনের জন্য অনেক বেশি স্ট্যান্ডার্ড।